rustc_ast_lowering/
lib.rs

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 more
5//! interesting and there are some invariants you should know about. These mostly
6//! concern spans and IDs.
7//!
8//! Spans are assigned to AST nodes during parsing and then are modified during
9//! expansion to indicate the origin of a node and the process it went through
10//! being expanded. IDs are assigned to AST nodes just before lowering.
11//!
12//! For the simpler lowering steps, IDs and spans should be preserved. Unlike
13//! expansion we do not preserve the process of lowering in the spans, so spans
14//! should not be modified here. When creating a new node (as opposed to
15//! "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 the
18//! ID from an AST node in a single HIR node (you can assume that AST node-IDs
19//! 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 to
23//! source code. It is therefore not as important with spans as IDs to be strict
24//! about use (you can't break the compiler by screwing up a span). Obviously, a
25//! HIR node can only have a single span. But multiple nodes can have the same
26//! span and spans don't need to be kept in order, etc. Where code is preserved
27//! by lowering, it should have the same span as in the AST. Where HIR nodes are
28//! 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 to
30//! get confused if the spans from leaf AST nodes occur in multiple places
31//! in the HIR, especially for multiple identifiers.
32
33// tidy-alphabetical-start
34#![allow(internal_features)]
35#![cfg_attr(bootstrap, feature(let_chains))]
36#![doc(rust_logo)]
37#![feature(assert_matches)]
38#![feature(box_patterns)]
39#![feature(exact_size_is_empty)]
40#![feature(if_let_guard)]
41#![feature(rustdoc_internals)]
42// tidy-alphabetical-end
43
44use std::sync::Arc;
45
46use rustc_ast::node_id::NodeMap;
47use rustc_ast::{self as ast, *};
48use rustc_attr_parsing::{AttributeParser, OmitDoc};
49use rustc_data_structures::fingerprint::Fingerprint;
50use rustc_data_structures::sorted_map::SortedMap;
51use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
52use rustc_data_structures::sync::spawn;
53use rustc_data_structures::tagged_ptr::TaggedRef;
54use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
55use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
56use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
57use rustc_hir::{
58    self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem,
59    LifetimeSource, LifetimeSyntax, ParamName, TraitCandidate,
60};
61use rustc_index::{Idx, IndexSlice, IndexVec};
62use rustc_macros::extension;
63use rustc_middle::span_bug;
64use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
65use rustc_session::parse::{add_feature_diagnostics, feature_err};
66use rustc_span::symbol::{Ident, Symbol, kw, sym};
67use rustc_span::{DUMMY_SP, DesugaringKind, Span};
68use smallvec::{SmallVec, smallvec};
69use thin_vec::ThinVec;
70use tracing::{debug, instrument, trace};
71
72use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
73
74macro_rules! arena_vec {
75    ($this:expr; $($x:expr),*) => (
76        $this.arena.alloc_from_iter([$($x),*])
77    );
78}
79
80mod asm;
81mod block;
82mod delegation;
83mod errors;
84mod expr;
85mod format;
86mod index;
87mod item;
88mod pat;
89mod path;
90pub mod stability;
91
92rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
93
94struct LoweringContext<'a, 'hir> {
95    tcx: TyCtxt<'hir>,
96    resolver: &'a mut ResolverAstLowering,
97
98    /// Used to allocate HIR nodes.
99    arena: &'hir hir::Arena<'hir>,
100
101    /// Bodies inside the owner being lowered.
102    bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
103    /// `#[define_opaque]` attributes
104    define_opaque: Option<&'hir [(Span, LocalDefId)]>,
105    /// Attributes inside the owner being lowered.
106    attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
107    /// Collect items that were created by lowering the current owner.
108    children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,
109
110    contract_ensures: Option<(Span, Ident, HirId)>,
111
112    coroutine_kind: Option<hir::CoroutineKind>,
113
114    /// When inside an `async` context, this is the `HirId` of the
115    /// `task_context` local bound to the resume argument of the coroutine.
116    task_context: Option<HirId>,
117
118    /// Used to get the current `fn`'s def span to point to when using `await`
119    /// outside of an `async fn`.
120    current_item: Option<Span>,
121
122    catch_scope: Option<HirId>,
123    loop_scope: Option<HirId>,
124    is_in_loop_condition: bool,
125    is_in_dyn_type: bool,
126
127    current_hir_id_owner: hir::OwnerId,
128    item_local_id_counter: hir::ItemLocalId,
129    trait_map: ItemLocalMap<Box<[TraitCandidate]>>,
130
131    impl_trait_defs: Vec<hir::GenericParam<'hir>>,
132    impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
133
134    /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.
135    ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,
136    /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.
137    #[cfg(debug_assertions)]
138    node_id_to_local_id: NodeMap<hir::ItemLocalId>,
139
140    allow_try_trait: Arc<[Symbol]>,
141    allow_gen_future: Arc<[Symbol]>,
142    allow_pattern_type: Arc<[Symbol]>,
143    allow_async_iterator: Arc<[Symbol]>,
144    allow_for_await: Arc<[Symbol]>,
145    allow_async_fn_traits: Arc<[Symbol]>,
146
147    attribute_parser: AttributeParser<'hir>,
148}
149
150impl<'a, 'hir> LoweringContext<'a, 'hir> {
151    fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
152        let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
153        Self {
154            // Pseudo-globals.
155            tcx,
156            resolver,
157            arena: tcx.hir_arena,
158
159            // HirId handling.
160            bodies: Vec::new(),
161            define_opaque: None,
162            attrs: SortedMap::default(),
163            children: Vec::default(),
164            contract_ensures: None,
165            current_hir_id_owner: hir::CRATE_OWNER_ID,
166            item_local_id_counter: hir::ItemLocalId::ZERO,
167            ident_and_label_to_local_id: Default::default(),
168            #[cfg(debug_assertions)]
169            node_id_to_local_id: Default::default(),
170            trait_map: Default::default(),
171
172            // Lowering state.
173            catch_scope: None,
174            loop_scope: None,
175            is_in_loop_condition: false,
176            is_in_dyn_type: false,
177            coroutine_kind: None,
178            task_context: None,
179            current_item: None,
180            impl_trait_defs: Vec::new(),
181            impl_trait_bounds: Vec::new(),
182            allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
183            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
184            allow_gen_future: if tcx.features().async_fn_track_caller() {
185                [sym::gen_future, sym::closure_track_caller].into()
186            } else {
187                [sym::gen_future].into()
188            },
189            allow_for_await: [sym::async_iterator].into(),
190            allow_async_fn_traits: [sym::async_fn_traits].into(),
191            // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`
192            // interact with `gen`/`async gen` blocks
193            allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),
194
195            attribute_parser: AttributeParser::new(tcx.sess, tcx.features(), registered_tools),
196        }
197    }
198
199    pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {
200        self.tcx.dcx()
201    }
202}
203
204#[extension(trait ResolverAstLoweringExt)]
205impl ResolverAstLowering {
206    fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
207        if let ExprKind::Path(None, path) = &expr.kind {
208            // Don't perform legacy const generics rewriting if the path already
209            // has generic arguments.
210            if path.segments.last().unwrap().args.is_some() {
211                return None;
212            }
213
214            if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
215                // We only support cross-crate argument rewriting. Uses
216                // within the same crate should be updated to use the new
217                // const generics style.
218                if def_id.is_local() {
219                    return None;
220                }
221
222                if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
223                    return v.clone();
224                }
225            }
226        }
227
228        None
229    }
230
231    fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
232        self.partial_res_map.get(&id).copied()
233    }
234
235    /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
236    fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
237        self.import_res_map.get(&id).copied().unwrap_or_default()
238    }
239
240    /// Obtains resolution for a label with the given `NodeId`.
241    fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
242        self.label_res_map.get(&id).copied()
243    }
244
245    /// Obtains resolution for a lifetime with the given `NodeId`.
246    fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
247        self.lifetimes_res_map.get(&id).copied()
248    }
249
250    /// Obtain the list of lifetimes parameters to add to an item.
251    ///
252    /// Extra lifetime parameters should only be added in places that can appear
253    /// as a `binder` in `LifetimeRes`.
254    ///
255    /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
256    /// should appear at the enclosing `PolyTraitRef`.
257    fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
258        self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default()
259    }
260}
261
262/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
263/// and if so, what meaning it has.
264#[derive(Debug, Copy, Clone, PartialEq, Eq)]
265enum ImplTraitContext {
266    /// Treat `impl Trait` as shorthand for a new universal generic parameter.
267    /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
268    /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
269    ///
270    /// Newly generated parameters should be inserted into the given `Vec`.
271    Universal,
272
273    /// Treat `impl Trait` as shorthand for a new opaque type.
274    /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
275    /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
276    ///
277    OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },
278
279    /// Treat `impl Trait` as a "trait ascription", which is like a type
280    /// variable but that also enforces that a set of trait goals hold.
281    ///
282    /// This is useful to guide inference for unnameable types.
283    InBinding,
284
285    /// `impl Trait` is unstably accepted in this position.
286    FeatureGated(ImplTraitPosition, Symbol),
287    /// `impl Trait` is not accepted in this position.
288    Disallowed(ImplTraitPosition),
289}
290
291/// Position in which `impl Trait` is disallowed.
292#[derive(Debug, Copy, Clone, PartialEq, Eq)]
293enum ImplTraitPosition {
294    Path,
295    Variable,
296    Trait,
297    Bound,
298    Generic,
299    ExternFnParam,
300    ClosureParam,
301    PointerParam,
302    FnTraitParam,
303    ExternFnReturn,
304    ClosureReturn,
305    PointerReturn,
306    FnTraitReturn,
307    GenericDefault,
308    ConstTy,
309    StaticTy,
310    AssocTy,
311    FieldTy,
312    Cast,
313    ImplSelf,
314    OffsetOf,
315}
316
317impl std::fmt::Display for ImplTraitPosition {
318    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319        let name = match self {
320            ImplTraitPosition::Path => "paths",
321            ImplTraitPosition::Variable => "the type of variable bindings",
322            ImplTraitPosition::Trait => "traits",
323            ImplTraitPosition::Bound => "bounds",
324            ImplTraitPosition::Generic => "generics",
325            ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
326            ImplTraitPosition::ClosureParam => "closure parameters",
327            ImplTraitPosition::PointerParam => "`fn` pointer parameters",
328            ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
329            ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
330            ImplTraitPosition::ClosureReturn => "closure return types",
331            ImplTraitPosition::PointerReturn => "`fn` pointer return types",
332            ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
333            ImplTraitPosition::GenericDefault => "generic parameter defaults",
334            ImplTraitPosition::ConstTy => "const types",
335            ImplTraitPosition::StaticTy => "static types",
336            ImplTraitPosition::AssocTy => "associated types",
337            ImplTraitPosition::FieldTy => "field types",
338            ImplTraitPosition::Cast => "cast expression types",
339            ImplTraitPosition::ImplSelf => "impl headers",
340            ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
341        };
342
343        write!(f, "{name}")
344    }
345}
346
347#[derive(Copy, Clone, Debug, PartialEq, Eq)]
348enum FnDeclKind {
349    Fn,
350    Inherent,
351    ExternFn,
352    Closure,
353    Pointer,
354    Trait,
355    Impl,
356}
357
358#[derive(Copy, Clone)]
359enum AstOwner<'a> {
360    NonOwner,
361    Crate(&'a ast::Crate),
362    Item(&'a ast::Item),
363    AssocItem(&'a ast::AssocItem, visit::AssocCtxt),
364    ForeignItem(&'a ast::ForeignItem),
365}
366
367fn index_crate<'a>(
368    node_id_to_def_id: &NodeMap<LocalDefId>,
369    krate: &'a Crate,
370) -> IndexVec<LocalDefId, AstOwner<'a>> {
371    let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
372    *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =
373        AstOwner::Crate(krate);
374    visit::walk_crate(&mut indexer, krate);
375    return indexer.index;
376
377    struct Indexer<'s, 'a> {
378        node_id_to_def_id: &'s NodeMap<LocalDefId>,
379        index: IndexVec<LocalDefId, AstOwner<'a>>,
380    }
381
382    impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> {
383        fn visit_attribute(&mut self, _: &'a Attribute) {
384            // We do not want to lower expressions that appear in attributes,
385            // as they are not accessible to the rest of the HIR.
386        }
387
388        fn visit_item(&mut self, item: &'a ast::Item) {
389            let def_id = self.node_id_to_def_id[&item.id];
390            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);
391            visit::walk_item(self, item)
392        }
393
394        fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
395            let def_id = self.node_id_to_def_id[&item.id];
396            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
397                AstOwner::AssocItem(item, ctxt);
398            visit::walk_assoc_item(self, item, ctxt);
399        }
400
401        fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
402            let def_id = self.node_id_to_def_id[&item.id];
403            *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =
404                AstOwner::ForeignItem(item);
405            visit::walk_item(self, item);
406        }
407    }
408}
409
410/// Compute the hash for the HIR of the full crate.
411/// This hash will then be part of the crate_hash which is stored in the metadata.
412fn compute_hir_hash(
413    tcx: TyCtxt<'_>,
414    owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
415) -> Fingerprint {
416    let mut hir_body_nodes: Vec<_> = owners
417        .iter_enumerated()
418        .filter_map(|(def_id, info)| {
419            let info = info.as_owner()?;
420            let def_path_hash = tcx.hir_def_path_hash(def_id);
421            Some((def_path_hash, info))
422        })
423        .collect();
424    hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
425
426    tcx.with_stable_hashing_context(|mut hcx| {
427        let mut stable_hasher = StableHasher::new();
428        hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
429        stable_hasher.finish()
430    })
431}
432
433pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
434    let sess = tcx.sess;
435    // Queries that borrow `resolver_for_lowering`.
436    tcx.ensure_done().output_filenames(());
437    tcx.ensure_done().early_lint_checks(());
438    tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);
439    tcx.ensure_done().get_lang_items(());
440    let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
441
442    let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
443    let mut owners = IndexVec::from_fn_n(
444        |_| hir::MaybeOwner::Phantom,
445        tcx.definitions_untracked().def_index_count(),
446    );
447
448    for def_id in ast_index.indices() {
449        item::ItemLowerer {
450            tcx,
451            resolver: &mut resolver,
452            ast_index: &ast_index,
453            owners: &mut owners,
454        }
455        .lower_node(def_id);
456    }
457
458    drop(ast_index);
459
460    // Drop AST to free memory. It can be expensive so try to drop it on a separate thread.
461    let prof = sess.prof.clone();
462    spawn(move || {
463        let _timer = prof.verbose_generic_activity("drop_ast");
464        drop(krate);
465    });
466
467    // Don't hash unless necessary, because it's expensive.
468    let opt_hir_hash =
469        if tcx.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
470    hir::Crate { owners, opt_hir_hash }
471}
472
473#[derive(Copy, Clone, PartialEq, Debug)]
474enum ParamMode {
475    /// Any path in a type context.
476    Explicit,
477    /// The `module::Type` in `module::Type::method` in an expression.
478    Optional,
479}
480
481#[derive(Copy, Clone, Debug)]
482enum AllowReturnTypeNotation {
483    /// Only in types, since RTN is denied later during HIR lowering.
484    Yes,
485    /// All other positions (path expr, method, use tree).
486    No,
487}
488
489enum GenericArgsMode {
490    /// Allow paren sugar, don't allow RTN.
491    ParenSugar,
492    /// Allow RTN, don't allow paren sugar.
493    ReturnTypeNotation,
494    // Error if parenthesized generics or RTN are encountered.
495    Err,
496    /// Silence errors when lowering generics. Only used with `Res::Err`.
497    Silence,
498}
499
500impl<'a, 'hir> LoweringContext<'a, 'hir> {
501    fn create_def(
502        &mut self,
503        node_id: ast::NodeId,
504        name: Option<Symbol>,
505        def_kind: DefKind,
506        span: Span,
507    ) -> LocalDefId {
508        let parent = self.current_hir_id_owner.def_id;
509        debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
510        assert!(
511            self.opt_local_def_id(node_id).is_none(),
512            "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
513            node_id,
514            def_kind,
515            self.tcx.hir_def_key(self.local_def_id(node_id)),
516        );
517
518        let def_id = self
519            .tcx
520            .at(span)
521            .create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator)
522            .def_id();
523
524        debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
525        self.resolver.node_id_to_def_id.insert(node_id, def_id);
526
527        def_id
528    }
529
530    fn next_node_id(&mut self) -> NodeId {
531        let start = self.resolver.next_node_id;
532        let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
533        self.resolver.next_node_id = ast::NodeId::from_u32(next);
534        start
535    }
536
537    /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
538    /// resolver (if any).
539    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
540        self.resolver.node_id_to_def_id.get(&node).copied()
541    }
542
543    fn local_def_id(&self, node: NodeId) -> LocalDefId {
544        self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
545    }
546
547    /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.
548    fn owner_id(&self, node: NodeId) -> hir::OwnerId {
549        hir::OwnerId { def_id: self.local_def_id(node) }
550    }
551
552    /// Freshen the `LoweringContext` and ready it to lower a nested item.
553    /// The lowered item is registered into `self.children`.
554    ///
555    /// This function sets up `HirId` lowering infrastructure,
556    /// and stashes the shared mutable state to avoid pollution by the closure.
557    #[instrument(level = "debug", skip(self, f))]
558    fn with_hir_id_owner(
559        &mut self,
560        owner: NodeId,
561        f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
562    ) {
563        let owner_id = self.owner_id(owner);
564
565        let current_attrs = std::mem::take(&mut self.attrs);
566        let current_bodies = std::mem::take(&mut self.bodies);
567        let current_define_opaque = std::mem::take(&mut self.define_opaque);
568        let current_ident_and_label_to_local_id =
569            std::mem::take(&mut self.ident_and_label_to_local_id);
570
571        #[cfg(debug_assertions)]
572        let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);
573        let current_trait_map = std::mem::take(&mut self.trait_map);
574        let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);
575        let current_local_counter =
576            std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
577        let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
578        let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
579
580        // Do not reset `next_node_id` and `node_id_to_def_id`:
581        // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
582        // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
583
584        // Always allocate the first `HirId` for the owner itself.
585        #[cfg(debug_assertions)]
586        {
587            let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
588            debug_assert_eq!(_old, None);
589        }
590
591        let item = f(self);
592        debug_assert_eq!(owner_id, item.def_id());
593        // `f` should have consumed all the elements in these vectors when constructing `item`.
594        debug_assert!(self.impl_trait_defs.is_empty());
595        debug_assert!(self.impl_trait_bounds.is_empty());
596        let info = self.make_owner_info(item);
597
598        self.attrs = current_attrs;
599        self.bodies = current_bodies;
600        self.define_opaque = current_define_opaque;
601        self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
602
603        #[cfg(debug_assertions)]
604        {
605            self.node_id_to_local_id = current_node_id_to_local_id;
606        }
607        self.trait_map = current_trait_map;
608        self.current_hir_id_owner = current_owner;
609        self.item_local_id_counter = current_local_counter;
610        self.impl_trait_defs = current_impl_trait_defs;
611        self.impl_trait_bounds = current_impl_trait_bounds;
612
613        debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));
614        self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));
615    }
616
617    fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
618        let attrs = std::mem::take(&mut self.attrs);
619        let mut bodies = std::mem::take(&mut self.bodies);
620        let define_opaque = std::mem::take(&mut self.define_opaque);
621        let trait_map = std::mem::take(&mut self.trait_map);
622
623        #[cfg(debug_assertions)]
624        for (id, attrs) in attrs.iter() {
625            // Verify that we do not store empty slices in the map.
626            if attrs.is_empty() {
627                panic!("Stored empty attributes for {:?}", id);
628            }
629        }
630
631        bodies.sort_by_key(|(k, _)| *k);
632        let bodies = SortedMap::from_presorted_elements(bodies);
633
634        // Don't hash unless necessary, because it's expensive.
635        let (opt_hash_including_bodies, attrs_hash) =
636            self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);
637        let num_nodes = self.item_local_id_counter.as_usize();
638        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
639        let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
640        let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
641
642        self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
643    }
644
645    /// This method allocates a new `HirId` for the given `NodeId`.
646    /// Take care not to call this method if the resulting `HirId` is then not
647    /// actually used in the HIR, as that would trigger an assertion in the
648    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
649    /// properly. Calling the method twice with the same `NodeId` is also forbidden.
650    #[instrument(level = "debug", skip(self), ret)]
651    fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {
652        assert_ne!(ast_node_id, DUMMY_NODE_ID);
653
654        let owner = self.current_hir_id_owner;
655        let local_id = self.item_local_id_counter;
656        assert_ne!(local_id, hir::ItemLocalId::ZERO);
657        self.item_local_id_counter.increment_by(1);
658        let hir_id = HirId { owner, local_id };
659
660        if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
661            self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
662        }
663
664        if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
665            self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
666        }
667
668        // Check whether the same `NodeId` is lowered more than once.
669        #[cfg(debug_assertions)]
670        {
671            let old = self.node_id_to_local_id.insert(ast_node_id, local_id);
672            assert_eq!(old, None);
673        }
674
675        hir_id
676    }
677
678    /// Generate a new `HirId` without a backing `NodeId`.
679    #[instrument(level = "debug", skip(self), ret)]
680    fn next_id(&mut self) -> HirId {
681        let owner = self.current_hir_id_owner;
682        let local_id = self.item_local_id_counter;
683        assert_ne!(local_id, hir::ItemLocalId::ZERO);
684        self.item_local_id_counter.increment_by(1);
685        HirId { owner, local_id }
686    }
687
688    #[instrument(level = "trace", skip(self))]
689    fn lower_res(&mut self, res: Res<NodeId>) -> Res {
690        let res: Result<Res, ()> = res.apply_id(|id| {
691            let owner = self.current_hir_id_owner;
692            let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;
693            Ok(HirId { owner, local_id })
694        });
695        trace!(?res);
696
697        // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
698        // This can happen when trying to lower the return type `x` in erroneous code like
699        //   async fn foo(x: u8) -> x {}
700        // In that case, `x` is lowered as a function parameter, and the return type is lowered as
701        // an opaque type as a synthesized HIR owner.
702        res.unwrap_or(Res::Err)
703    }
704
705    fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
706        self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
707    }
708
709    fn lower_import_res(&mut self, id: NodeId, span: Span) -> SmallVec<[Res; 3]> {
710        let res = self.resolver.get_import_res(id).present_items();
711        let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect();
712        if res.is_empty() {
713            self.dcx().span_delayed_bug(span, "no resolution for an import");
714            return smallvec![Res::Err];
715        }
716        res
717    }
718
719    fn make_lang_item_qpath(
720        &mut self,
721        lang_item: hir::LangItem,
722        span: Span,
723        args: Option<&'hir hir::GenericArgs<'hir>>,
724    ) -> hir::QPath<'hir> {
725        hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
726    }
727
728    fn make_lang_item_path(
729        &mut self,
730        lang_item: hir::LangItem,
731        span: Span,
732        args: Option<&'hir hir::GenericArgs<'hir>>,
733    ) -> &'hir hir::Path<'hir> {
734        let def_id = self.tcx.require_lang_item(lang_item, Some(span));
735        let def_kind = self.tcx.def_kind(def_id);
736        let res = Res::Def(def_kind, def_id);
737        self.arena.alloc(hir::Path {
738            span,
739            res,
740            segments: self.arena.alloc_from_iter([hir::PathSegment {
741                ident: Ident::new(lang_item.name(), span),
742                hir_id: self.next_id(),
743                res,
744                args,
745                infer_args: args.is_none(),
746            }]),
747        })
748    }
749
750    /// Reuses the span but adds information like the kind of the desugaring and features that are
751    /// allowed inside this span.
752    fn mark_span_with_reason(
753        &self,
754        reason: DesugaringKind,
755        span: Span,
756        allow_internal_unstable: Option<Arc<[Symbol]>>,
757    ) -> Span {
758        self.tcx.with_stable_hashing_context(|hcx| {
759            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
760        })
761    }
762
763    /// Intercept all spans entering HIR.
764    /// Mark a span as relative to the current owning item.
765    fn lower_span(&self, span: Span) -> Span {
766        if self.tcx.sess.opts.incremental.is_some() {
767            span.with_parent(Some(self.current_hir_id_owner.def_id))
768        } else {
769            // Do not make spans relative when not using incremental compilation.
770            span
771        }
772    }
773
774    fn lower_ident(&self, ident: Ident) -> Ident {
775        Ident::new(ident.name, self.lower_span(ident.span))
776    }
777
778    /// Converts a lifetime into a new generic parameter.
779    #[instrument(level = "debug", skip(self))]
780    fn lifetime_res_to_generic_param(
781        &mut self,
782        ident: Ident,
783        node_id: NodeId,
784        res: LifetimeRes,
785        source: hir::GenericParamSource,
786    ) -> Option<hir::GenericParam<'hir>> {
787        let (name, kind) = match res {
788            LifetimeRes::Param { .. } => {
789                (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
790            }
791            LifetimeRes::Fresh { param, kind, .. } => {
792                // Late resolution delegates to us the creation of the `LocalDefId`.
793                let _def_id = self.create_def(
794                    param,
795                    Some(kw::UnderscoreLifetime),
796                    DefKind::LifetimeParam,
797                    ident.span,
798                );
799                debug!(?_def_id);
800
801                (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
802            }
803            LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
804            res => panic!(
805                "Unexpected lifetime resolution {:?} for {:?} at {:?}",
806                res, ident, ident.span
807            ),
808        };
809        let hir_id = self.lower_node_id(node_id);
810        let def_id = self.local_def_id(node_id);
811        Some(hir::GenericParam {
812            hir_id,
813            def_id,
814            name,
815            span: self.lower_span(ident.span),
816            pure_wrt_drop: false,
817            kind: hir::GenericParamKind::Lifetime { kind },
818            colon_span: None,
819            source,
820        })
821    }
822
823    /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR
824    /// nodes. The returned list includes any "extra" lifetime parameters that were added by the
825    /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
826    /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
827    /// parameters will be successful.
828    #[instrument(level = "debug", skip(self))]
829    #[inline]
830    fn lower_lifetime_binder(
831        &mut self,
832        binder: NodeId,
833        generic_params: &[GenericParam],
834    ) -> &'hir [hir::GenericParam<'hir>] {
835        let mut generic_params: Vec<_> = self
836            .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
837            .collect();
838        let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
839        debug!(?extra_lifetimes);
840        generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
841            self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
842        }));
843        let generic_params = self.arena.alloc_from_iter(generic_params);
844        debug!(?generic_params);
845
846        generic_params
847    }
848
849    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
850        let was_in_dyn_type = self.is_in_dyn_type;
851        self.is_in_dyn_type = in_scope;
852
853        let result = f(self);
854
855        self.is_in_dyn_type = was_in_dyn_type;
856
857        result
858    }
859
860    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
861        let current_item = self.current_item;
862        self.current_item = Some(scope_span);
863
864        let was_in_loop_condition = self.is_in_loop_condition;
865        self.is_in_loop_condition = false;
866
867        let old_contract = self.contract_ensures.take();
868
869        let catch_scope = self.catch_scope.take();
870        let loop_scope = self.loop_scope.take();
871        let ret = f(self);
872        self.catch_scope = catch_scope;
873        self.loop_scope = loop_scope;
874
875        self.contract_ensures = old_contract;
876
877        self.is_in_loop_condition = was_in_loop_condition;
878
879        self.current_item = current_item;
880
881        ret
882    }
883
884    fn lower_attrs(
885        &mut self,
886        id: HirId,
887        attrs: &[Attribute],
888        target_span: Span,
889    ) -> &'hir [hir::Attribute] {
890        if attrs.is_empty() {
891            &[]
892        } else {
893            let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span));
894
895            debug_assert_eq!(id.owner, self.current_hir_id_owner);
896            let ret = self.arena.alloc_from_iter(lowered_attrs);
897
898            // this is possible if an item contained syntactical attribute,
899            // but none of them parse succesfully or all of them were ignored
900            // for not being built-in attributes at all. They could be remaining
901            // unexpanded attributes used as markers in proc-macro derives for example.
902            // This will have emitted some diagnostics for the misparse, but will then
903            // not emit the attribute making the list empty.
904            if ret.is_empty() {
905                &[]
906            } else {
907                self.attrs.insert(id.local_id, ret);
908                ret
909            }
910        }
911    }
912
913    fn lower_attrs_vec(&self, attrs: &[Attribute], target_span: Span) -> Vec<hir::Attribute> {
914        self.attribute_parser
915            .parse_attribute_list(attrs, target_span, OmitDoc::Lower, |s| self.lower_span(s))
916    }
917
918    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
919        debug_assert_eq!(id.owner, self.current_hir_id_owner);
920        debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
921        if let Some(&a) = self.attrs.get(&target_id.local_id) {
922            debug_assert!(!a.is_empty());
923            self.attrs.insert(id.local_id, a);
924        }
925    }
926
927    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
928        args.clone()
929    }
930
931    /// Lower an associated item constraint.
932    #[instrument(level = "debug", skip_all)]
933    fn lower_assoc_item_constraint(
934        &mut self,
935        constraint: &AssocItemConstraint,
936        itctx: ImplTraitContext,
937    ) -> hir::AssocItemConstraint<'hir> {
938        debug!(?constraint, ?itctx);
939        // Lower the generic arguments for the associated item.
940        let gen_args = if let Some(gen_args) = &constraint.gen_args {
941            let gen_args_ctor = match gen_args {
942                GenericArgs::AngleBracketed(data) => {
943                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
944                }
945                GenericArgs::Parenthesized(data) => {
946                    if let Some(first_char) = constraint.ident.as_str().chars().next()
947                        && first_char.is_ascii_lowercase()
948                    {
949                        let err = match (&data.inputs[..], &data.output) {
950                            ([_, ..], FnRetTy::Default(_)) => {
951                                errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
952                            }
953                            ([], FnRetTy::Default(_)) => {
954                                errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
955                            }
956                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.
957                            (_, FnRetTy::Ty(ty)) => {
958                                let span = data.inputs_span.shrink_to_hi().to(ty.span);
959                                errors::BadReturnTypeNotation::Output {
960                                    span,
961                                    suggestion: errors::RTNSuggestion {
962                                        output: span,
963                                        input: data.inputs_span,
964                                    },
965                                }
966                            }
967                        };
968                        let mut err = self.dcx().create_err(err);
969                        if !self.tcx.features().return_type_notation()
970                            && self.tcx.sess.is_nightly_build()
971                        {
972                            add_feature_diagnostics(
973                                &mut err,
974                                &self.tcx.sess,
975                                sym::return_type_notation,
976                            );
977                        }
978                        err.emit();
979                        GenericArgsCtor {
980                            args: Default::default(),
981                            constraints: &[],
982                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
983                            span: data.span,
984                        }
985                    } else {
986                        self.emit_bad_parenthesized_trait_in_assoc_ty(data);
987                        // FIXME(return_type_notation): we could issue a feature error
988                        // if the parens are empty and there's no return type.
989                        self.lower_angle_bracketed_parameter_data(
990                            &data.as_angle_bracketed_args(),
991                            ParamMode::Explicit,
992                            itctx,
993                        )
994                        .0
995                    }
996                }
997                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
998                    args: Default::default(),
999                    constraints: &[],
1000                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1001                    span: *span,
1002                },
1003            };
1004            gen_args_ctor.into_generic_args(self)
1005        } else {
1006            self.arena.alloc(hir::GenericArgs::none())
1007        };
1008        let kind = match &constraint.kind {
1009            AssocItemConstraintKind::Equality { term } => {
1010                let term = match term {
1011                    Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1012                    Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1013                };
1014                hir::AssocItemConstraintKind::Equality { term }
1015            }
1016            AssocItemConstraintKind::Bound { bounds } => {
1017                // Disallow ATB in dyn types
1018                if self.is_in_dyn_type {
1019                    let suggestion = match itctx {
1020                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1021                            let bound_end_span = constraint
1022                                .gen_args
1023                                .as_ref()
1024                                .map_or(constraint.ident.span, |args| args.span());
1025                            if bound_end_span.eq_ctxt(constraint.span) {
1026                                Some(self.tcx.sess.source_map().next_point(bound_end_span))
1027                            } else {
1028                                None
1029                            }
1030                        }
1031                        _ => None,
1032                    };
1033
1034                    let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1035                        span: constraint.span,
1036                        suggestion,
1037                    });
1038                    let err_ty =
1039                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1040                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1041                } else {
1042                    // Desugar `AssocTy: Bounds` into an assoc type binding where the
1043                    // later desugars into a trait predicate.
1044                    let bounds = self.lower_param_bounds(bounds, itctx);
1045
1046                    hir::AssocItemConstraintKind::Bound { bounds }
1047                }
1048            }
1049        };
1050
1051        hir::AssocItemConstraint {
1052            hir_id: self.lower_node_id(constraint.id),
1053            ident: self.lower_ident(constraint.ident),
1054            gen_args,
1055            kind,
1056            span: self.lower_span(constraint.span),
1057        }
1058    }
1059
1060    fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1061        // Suggest removing empty parentheses: "Trait()" -> "Trait"
1062        let sub = if data.inputs.is_empty() {
1063            let parentheses_span =
1064                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1065            AssocTyParenthesesSub::Empty { parentheses_span }
1066        }
1067        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1068        else {
1069            // Start of parameters to the 1st argument
1070            let open_param = data.inputs_span.shrink_to_lo().to(data
1071                .inputs
1072                .first()
1073                .unwrap()
1074                .span
1075                .shrink_to_lo());
1076            // End of last argument to end of parameters
1077            let close_param =
1078                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1079            AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1080        };
1081        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1082    }
1083
1084    #[instrument(level = "debug", skip(self))]
1085    fn lower_generic_arg(
1086        &mut self,
1087        arg: &ast::GenericArg,
1088        itctx: ImplTraitContext,
1089    ) -> hir::GenericArg<'hir> {
1090        match arg {
1091            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1092                lt,
1093                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1094                lt.ident.into(),
1095            )),
1096            ast::GenericArg::Type(ty) => {
1097                // We cannot just match on `TyKind::Infer` as `(_)` is represented as
1098                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`
1099                if ty.is_maybe_parenthesised_infer() {
1100                    return GenericArg::Infer(hir::InferArg {
1101                        hir_id: self.lower_node_id(ty.id),
1102                        span: self.lower_span(ty.span),
1103                    });
1104                }
1105
1106                match &ty.kind {
1107                    // We parse const arguments as path types as we cannot distinguish them during
1108                    // parsing. We try to resolve that ambiguity by attempting resolution in both the
1109                    // type and value namespaces. If we resolved the path in the value namespace, we
1110                    // transform it into a generic const argument.
1111                    //
1112                    // FIXME: Should we be handling `(PATH_TO_CONST)`?
1113                    TyKind::Path(None, path) => {
1114                        if let Some(res) = self
1115                            .resolver
1116                            .get_partial_res(ty.id)
1117                            .and_then(|partial_res| partial_res.full_res())
1118                        {
1119                            if !res.matches_ns(Namespace::TypeNS)
1120                                && path.is_potential_trivial_const_arg(false)
1121                            {
1122                                debug!(
1123                                    "lower_generic_arg: Lowering type argument as const argument: {:?}",
1124                                    ty,
1125                                );
1126
1127                                let ct =
1128                                    self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1129                                return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1130                            }
1131                        }
1132                    }
1133                    _ => {}
1134                }
1135                GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1136            }
1137            ast::GenericArg::Const(ct) => {
1138                GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1139            }
1140        }
1141    }
1142
1143    #[instrument(level = "debug", skip(self))]
1144    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1145        self.arena.alloc(self.lower_ty_direct(t, itctx))
1146    }
1147
1148    fn lower_path_ty(
1149        &mut self,
1150        t: &Ty,
1151        qself: &Option<ptr::P<QSelf>>,
1152        path: &Path,
1153        param_mode: ParamMode,
1154        itctx: ImplTraitContext,
1155    ) -> hir::Ty<'hir> {
1156        // Check whether we should interpret this as a bare trait object.
1157        // This check mirrors the one in late resolution. We only introduce this special case in
1158        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.
1159        // The other cases when a qpath should be opportunistically made a trait object are handled
1160        // by `ty_path`.
1161        if qself.is_none()
1162            && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1163            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1164        {
1165            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1166                let bound = this.lower_poly_trait_ref(
1167                    &PolyTraitRef {
1168                        bound_generic_params: ThinVec::new(),
1169                        modifiers: TraitBoundModifiers::NONE,
1170                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1171                        span: t.span,
1172                    },
1173                    itctx,
1174                );
1175                let bounds = this.arena.alloc_from_iter([bound]);
1176                let lifetime_bound = this.elided_dyn_bound(t.span);
1177                (bounds, lifetime_bound)
1178            });
1179            let kind = hir::TyKind::TraitObject(
1180                bounds,
1181                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1182            );
1183            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1184        }
1185
1186        let id = self.lower_node_id(t.id);
1187        let qpath = self.lower_qpath(
1188            t.id,
1189            qself,
1190            path,
1191            param_mode,
1192            AllowReturnTypeNotation::Yes,
1193            itctx,
1194            None,
1195        );
1196        self.ty_path(id, t.span, qpath)
1197    }
1198
1199    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1200        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1201    }
1202
1203    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1204        self.ty(span, hir::TyKind::Tup(tys))
1205    }
1206
1207    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1208        let kind = match &t.kind {
1209            TyKind::Infer => hir::TyKind::Infer(()),
1210            TyKind::Err(guar) => hir::TyKind::Err(*guar),
1211            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1212            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1213            TyKind::Ref(region, mt) => {
1214                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1215                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1216            }
1217            TyKind::PinnedRef(region, mt) => {
1218                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1219                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1220                let span = self.lower_span(t.span);
1221                let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1222                let args = self.arena.alloc(hir::GenericArgs {
1223                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1224                    constraints: &[],
1225                    parenthesized: hir::GenericArgsParentheses::No,
1226                    span_ext: span,
1227                });
1228                let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1229                hir::TyKind::Path(path)
1230            }
1231            TyKind::BareFn(f) => {
1232                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1233                hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1234                    generic_params,
1235                    safety: self.lower_safety(f.safety, hir::Safety::Safe),
1236                    abi: self.lower_extern(f.ext),
1237                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1238                    param_idents: self.lower_fn_params_to_idents(&f.decl),
1239                }))
1240            }
1241            TyKind::UnsafeBinder(f) => {
1242                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1243                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1244                    generic_params,
1245                    inner_ty: self.lower_ty(&f.inner_ty, itctx),
1246                }))
1247            }
1248            TyKind::Never => hir::TyKind::Never,
1249            TyKind::Tup(tys) => hir::TyKind::Tup(
1250                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1251            ),
1252            TyKind::Paren(ty) => {
1253                return self.lower_ty_direct(ty, itctx);
1254            }
1255            TyKind::Path(qself, path) => {
1256                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1257            }
1258            TyKind::ImplicitSelf => {
1259                let hir_id = self.next_id();
1260                let res = self.expect_full_res(t.id);
1261                let res = self.lower_res(res);
1262                hir::TyKind::Path(hir::QPath::Resolved(
1263                    None,
1264                    self.arena.alloc(hir::Path {
1265                        res,
1266                        segments: arena_vec![self; hir::PathSegment::new(
1267                            Ident::with_dummy_span(kw::SelfUpper),
1268                            hir_id,
1269                            res
1270                        )],
1271                        span: self.lower_span(t.span),
1272                    }),
1273                ))
1274            }
1275            TyKind::Array(ty, length) => hir::TyKind::Array(
1276                self.lower_ty(ty, itctx),
1277                self.lower_array_length_to_const_arg(length),
1278            ),
1279            TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1280            TyKind::TraitObject(bounds, kind) => {
1281                let mut lifetime_bound = None;
1282                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1283                    let bounds =
1284                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1285                            // We can safely ignore constness here since AST validation
1286                            // takes care of rejecting invalid modifier combinations and
1287                            // const trait bounds in trait object types.
1288                            GenericBound::Trait(ty) => {
1289                                let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1290                                Some(trait_ref)
1291                            }
1292                            GenericBound::Outlives(lifetime) => {
1293                                if lifetime_bound.is_none() {
1294                                    lifetime_bound = Some(this.lower_lifetime(
1295                                        lifetime,
1296                                        LifetimeSource::Other,
1297                                        lifetime.ident.into(),
1298                                    ));
1299                                }
1300                                None
1301                            }
1302                            // Ignore `use` syntax since that is not valid in objects.
1303                            GenericBound::Use(_, span) => {
1304                                this.dcx()
1305                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");
1306                                None
1307                            }
1308                        }));
1309                    let lifetime_bound =
1310                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1311                    (bounds, lifetime_bound)
1312                });
1313                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1314            }
1315            TyKind::ImplTrait(def_node_id, bounds) => {
1316                let span = t.span;
1317                match itctx {
1318                    ImplTraitContext::OpaqueTy { origin } => {
1319                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1320                    }
1321                    ImplTraitContext::Universal => {
1322                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1323                            ast::GenericBound::Use(_, span) => Some(span),
1324                            _ => None,
1325                        }) {
1326                            self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1327                        }
1328
1329                        let def_id = self.local_def_id(*def_node_id);
1330                        let name = self.tcx.item_name(def_id.to_def_id());
1331                        let ident = Ident::new(name, span);
1332                        let (param, bounds, path) = self.lower_universal_param_and_bounds(
1333                            *def_node_id,
1334                            span,
1335                            ident,
1336                            bounds,
1337                        );
1338                        self.impl_trait_defs.push(param);
1339                        if let Some(bounds) = bounds {
1340                            self.impl_trait_bounds.push(bounds);
1341                        }
1342                        path
1343                    }
1344                    ImplTraitContext::InBinding => {
1345                        hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1346                    }
1347                    ImplTraitContext::FeatureGated(position, feature) => {
1348                        let guar = self
1349                            .tcx
1350                            .sess
1351                            .create_feature_err(
1352                                MisplacedImplTrait {
1353                                    span: t.span,
1354                                    position: DiagArgFromDisplay(&position),
1355                                },
1356                                feature,
1357                            )
1358                            .emit();
1359                        hir::TyKind::Err(guar)
1360                    }
1361                    ImplTraitContext::Disallowed(position) => {
1362                        let guar = self.dcx().emit_err(MisplacedImplTrait {
1363                            span: t.span,
1364                            position: DiagArgFromDisplay(&position),
1365                        });
1366                        hir::TyKind::Err(guar)
1367                    }
1368                }
1369            }
1370            TyKind::Pat(ty, pat) => {
1371                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1372            }
1373            TyKind::MacCall(_) => {
1374                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1375            }
1376            TyKind::CVarArgs => {
1377                let guar = self.dcx().span_delayed_bug(
1378                    t.span,
1379                    "`TyKind::CVarArgs` should have been handled elsewhere",
1380                );
1381                hir::TyKind::Err(guar)
1382            }
1383            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1384        };
1385
1386        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1387    }
1388
1389    fn lower_ty_direct_lifetime(
1390        &mut self,
1391        t: &Ty,
1392        region: Option<Lifetime>,
1393    ) -> &'hir hir::Lifetime {
1394        let (region, syntax) = match region {
1395            Some(region) => (region, region.ident.into()),
1396
1397            None => {
1398                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1399                    self.resolver.get_lifetime_res(t.id)
1400                {
1401                    debug_assert_eq!(start.plus(1), end);
1402                    start
1403                } else {
1404                    self.next_node_id()
1405                };
1406                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1407                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1408                (region, LifetimeSyntax::Hidden)
1409            }
1410        };
1411        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
1412    }
1413
1414    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1415    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1416    /// HIR type that references the TAIT.
1417    ///
1418    /// Given a function definition like:
1419    ///
1420    /// ```rust
1421    /// use std::fmt::Debug;
1422    ///
1423    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1424    ///     x
1425    /// }
1426    /// ```
1427    ///
1428    /// we will create a TAIT definition in the HIR like
1429    ///
1430    /// ```rust,ignore (pseudo-Rust)
1431    /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1432    /// ```
1433    ///
1434    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1435    ///
1436    /// ```rust,ignore (pseudo-Rust)
1437    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1438    /// ```
1439    ///
1440    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1441    /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1442    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1443    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1444    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1445    #[instrument(level = "debug", skip(self), ret)]
1446    fn lower_opaque_impl_trait(
1447        &mut self,
1448        span: Span,
1449        origin: hir::OpaqueTyOrigin<LocalDefId>,
1450        opaque_ty_node_id: NodeId,
1451        bounds: &GenericBounds,
1452        itctx: ImplTraitContext,
1453    ) -> hir::TyKind<'hir> {
1454        // Make sure we know that some funky desugaring has been going on here.
1455        // This is a first: there is code in other places like for loop
1456        // desugaring that explicitly states that we don't want to track that.
1457        // Not tracking it makes lints in rustc and clippy very fragile, as
1458        // frequently opened issues show.
1459        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1460
1461        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1462            this.lower_param_bounds(bounds, itctx)
1463        })
1464    }
1465
1466    fn lower_opaque_inner(
1467        &mut self,
1468        opaque_ty_node_id: NodeId,
1469        origin: hir::OpaqueTyOrigin<LocalDefId>,
1470        opaque_ty_span: Span,
1471        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1472    ) -> hir::TyKind<'hir> {
1473        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1474        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1475        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1476
1477        let bounds = lower_item_bounds(self);
1478        let opaque_ty_def = hir::OpaqueTy {
1479            hir_id: opaque_ty_hir_id,
1480            def_id: opaque_ty_def_id,
1481            bounds,
1482            origin,
1483            span: self.lower_span(opaque_ty_span),
1484        };
1485        let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1486
1487        hir::TyKind::OpaqueDef(opaque_ty_def)
1488    }
1489
1490    fn lower_precise_capturing_args(
1491        &mut self,
1492        precise_capturing_args: &[PreciseCapturingArg],
1493    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1494        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1495            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1496                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1497            ),
1498            PreciseCapturingArg::Arg(path, id) => {
1499                let [segment] = path.segments.as_slice() else {
1500                    panic!();
1501                };
1502                let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1503                    partial_res.full_res().expect("no partial res expected for precise capture arg")
1504                });
1505                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1506                    hir_id: self.lower_node_id(*id),
1507                    ident: self.lower_ident(segment.ident),
1508                    res: self.lower_res(res),
1509                })
1510            }
1511        }))
1512    }
1513
1514    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1515        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1516            PatKind::Missing => None,
1517            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1518            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1519            _ => {
1520                self.dcx().span_delayed_bug(
1521                    param.pat.span,
1522                    "non-missing/ident/wild param pat must trigger an error",
1523                );
1524                None
1525            }
1526        }))
1527    }
1528
1529    /// Lowers a function declaration.
1530    ///
1531    /// `decl`: the unlowered (AST) function declaration.
1532    ///
1533    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given
1534    /// `NodeId`.
1535    ///
1536    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is
1537    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.
1538    #[instrument(level = "debug", skip(self))]
1539    fn lower_fn_decl(
1540        &mut self,
1541        decl: &FnDecl,
1542        fn_node_id: NodeId,
1543        fn_span: Span,
1544        kind: FnDeclKind,
1545        coro: Option<CoroutineKind>,
1546    ) -> &'hir hir::FnDecl<'hir> {
1547        let c_variadic = decl.c_variadic();
1548
1549        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1550        // as they are not explicit in HIR/Ty function signatures.
1551        // (instead, the `c_variadic` flag is set to `true`)
1552        let mut inputs = &decl.inputs[..];
1553        if c_variadic {
1554            inputs = &inputs[..inputs.len() - 1];
1555        }
1556        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1557            let itctx = match kind {
1558                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1559                    ImplTraitContext::Universal
1560                }
1561                FnDeclKind::ExternFn => {
1562                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1563                }
1564                FnDeclKind::Closure => {
1565                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1566                }
1567                FnDeclKind::Pointer => {
1568                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1569                }
1570            };
1571            self.lower_ty_direct(&param.ty, itctx)
1572        }));
1573
1574        let output = match coro {
1575            Some(coro) => {
1576                let fn_def_id = self.local_def_id(fn_node_id);
1577                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1578            }
1579            None => match &decl.output {
1580                FnRetTy::Ty(ty) => {
1581                    let itctx = match kind {
1582                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1583                            origin: hir::OpaqueTyOrigin::FnReturn {
1584                                parent: self.local_def_id(fn_node_id),
1585                                in_trait_or_impl: None,
1586                            },
1587                        },
1588                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1589                            origin: hir::OpaqueTyOrigin::FnReturn {
1590                                parent: self.local_def_id(fn_node_id),
1591                                in_trait_or_impl: Some(hir::RpitContext::Trait),
1592                            },
1593                        },
1594                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1595                            origin: hir::OpaqueTyOrigin::FnReturn {
1596                                parent: self.local_def_id(fn_node_id),
1597                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1598                            },
1599                        },
1600                        FnDeclKind::ExternFn => {
1601                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1602                        }
1603                        FnDeclKind::Closure => {
1604                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1605                        }
1606                        FnDeclKind::Pointer => {
1607                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1608                        }
1609                    };
1610                    hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1611                }
1612                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1613            },
1614        };
1615
1616        self.arena.alloc(hir::FnDecl {
1617            inputs,
1618            output,
1619            c_variadic,
1620            lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1621            implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1622                let is_mutable_pat = matches!(
1623                    arg.pat.kind,
1624                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1625                );
1626
1627                match &arg.ty.kind {
1628                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1629                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1630                    // Given we are only considering `ImplicitSelf` types, we needn't consider
1631                    // the case where we have a mutable pattern to a reference as that would
1632                    // no longer be an `ImplicitSelf`.
1633                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1634                        if mt.ty.kind.is_implicit_self() =>
1635                    {
1636                        match mt.mutbl {
1637                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1638                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1639                        }
1640                    }
1641                    _ => hir::ImplicitSelfKind::None,
1642                }
1643            }),
1644        })
1645    }
1646
1647    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1648    // combined with the following definition of `OpaqueTy`:
1649    //
1650    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1651    //
1652    // `output`: unlowered output type (`T` in `-> T`)
1653    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)
1654    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1655    #[instrument(level = "debug", skip(self))]
1656    fn lower_coroutine_fn_ret_ty(
1657        &mut self,
1658        output: &FnRetTy,
1659        fn_def_id: LocalDefId,
1660        coro: CoroutineKind,
1661        fn_kind: FnDeclKind,
1662        fn_span: Span,
1663    ) -> hir::FnRetTy<'hir> {
1664        let span = self.lower_span(fn_span);
1665
1666        let (opaque_ty_node_id, allowed_features) = match coro {
1667            CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1668            CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1669            CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1670                (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1671            }
1672        };
1673
1674        let opaque_ty_span =
1675            self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1676
1677        let in_trait_or_impl = match fn_kind {
1678            FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1679            FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1680            FnDeclKind::Fn | FnDeclKind::Inherent => None,
1681            FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1682        };
1683
1684        let opaque_ty_ref = self.lower_opaque_inner(
1685            opaque_ty_node_id,
1686            hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1687            opaque_ty_span,
1688            |this| {
1689                let bound = this.lower_coroutine_fn_output_type_to_bound(
1690                    output,
1691                    coro,
1692                    opaque_ty_span,
1693                    ImplTraitContext::OpaqueTy {
1694                        origin: hir::OpaqueTyOrigin::FnReturn {
1695                            parent: fn_def_id,
1696                            in_trait_or_impl,
1697                        },
1698                    },
1699                );
1700                arena_vec![this; bound]
1701            },
1702        );
1703
1704        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1705        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1706    }
1707
1708    /// Transforms `-> T` into `Future<Output = T>`.
1709    fn lower_coroutine_fn_output_type_to_bound(
1710        &mut self,
1711        output: &FnRetTy,
1712        coro: CoroutineKind,
1713        opaque_ty_span: Span,
1714        itctx: ImplTraitContext,
1715    ) -> hir::GenericBound<'hir> {
1716        // Compute the `T` in `Future<Output = T>` from the return type.
1717        let output_ty = match output {
1718            FnRetTy::Ty(ty) => {
1719                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1720                // `impl Future` opaque type that `async fn` implicitly
1721                // generates.
1722                self.lower_ty(ty, itctx)
1723            }
1724            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1725        };
1726
1727        // "<$assoc_ty_name = T>"
1728        let (assoc_ty_name, trait_lang_item) = match coro {
1729            CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1730            CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1731            CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1732        };
1733
1734        let bound_args = self.arena.alloc(hir::GenericArgs {
1735            args: &[],
1736            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1737            parenthesized: hir::GenericArgsParentheses::No,
1738            span_ext: DUMMY_SP,
1739        });
1740
1741        hir::GenericBound::Trait(hir::PolyTraitRef {
1742            bound_generic_params: &[],
1743            modifiers: hir::TraitBoundModifiers::NONE,
1744            trait_ref: hir::TraitRef {
1745                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1746                hir_ref_id: self.next_id(),
1747            },
1748            span: opaque_ty_span,
1749        })
1750    }
1751
1752    #[instrument(level = "trace", skip(self))]
1753    fn lower_param_bound(
1754        &mut self,
1755        tpb: &GenericBound,
1756        itctx: ImplTraitContext,
1757    ) -> hir::GenericBound<'hir> {
1758        match tpb {
1759            GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1760            GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1761                lifetime,
1762                LifetimeSource::OutlivesBound,
1763                lifetime.ident.into(),
1764            )),
1765            GenericBound::Use(args, span) => hir::GenericBound::Use(
1766                self.lower_precise_capturing_args(args),
1767                self.lower_span(*span),
1768            ),
1769        }
1770    }
1771
1772    fn lower_lifetime(
1773        &mut self,
1774        l: &Lifetime,
1775        source: LifetimeSource,
1776        syntax: LifetimeSyntax,
1777    ) -> &'hir hir::Lifetime {
1778        self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1779    }
1780
1781    fn lower_lifetime_hidden_in_path(
1782        &mut self,
1783        id: NodeId,
1784        span: Span,
1785        angle_brackets: AngleBrackets,
1786    ) -> &'hir hir::Lifetime {
1787        self.new_named_lifetime(
1788            id,
1789            id,
1790            Ident::new(kw::UnderscoreLifetime, span),
1791            LifetimeSource::Path { angle_brackets },
1792            LifetimeSyntax::Hidden,
1793        )
1794    }
1795
1796    #[instrument(level = "debug", skip(self))]
1797    fn new_named_lifetime(
1798        &mut self,
1799        id: NodeId,
1800        new_id: NodeId,
1801        ident: Ident,
1802        source: LifetimeSource,
1803        syntax: LifetimeSyntax,
1804    ) -> &'hir hir::Lifetime {
1805        let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1806        let res = match res {
1807            LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1808            LifetimeRes::Fresh { param, .. } => {
1809                debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1810                let param = self.local_def_id(param);
1811                hir::LifetimeKind::Param(param)
1812            }
1813            LifetimeRes::Infer => {
1814                debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1815                hir::LifetimeKind::Infer
1816            }
1817            LifetimeRes::Static { .. } => {
1818                debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1819                hir::LifetimeKind::Static
1820            }
1821            LifetimeRes::Error => hir::LifetimeKind::Error,
1822            LifetimeRes::ElidedAnchor { .. } => {
1823                panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1824            }
1825        };
1826
1827        debug!(?res);
1828        self.arena.alloc(hir::Lifetime::new(
1829            self.lower_node_id(new_id),
1830            self.lower_ident(ident),
1831            res,
1832            source,
1833            syntax,
1834        ))
1835    }
1836
1837    fn lower_generic_params_mut(
1838        &mut self,
1839        params: &[GenericParam],
1840        source: hir::GenericParamSource,
1841    ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1842        params.iter().map(move |param| self.lower_generic_param(param, source))
1843    }
1844
1845    fn lower_generic_params(
1846        &mut self,
1847        params: &[GenericParam],
1848        source: hir::GenericParamSource,
1849    ) -> &'hir [hir::GenericParam<'hir>] {
1850        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1851    }
1852
1853    #[instrument(level = "trace", skip(self))]
1854    fn lower_generic_param(
1855        &mut self,
1856        param: &GenericParam,
1857        source: hir::GenericParamSource,
1858    ) -> hir::GenericParam<'hir> {
1859        let (name, kind) = self.lower_generic_param_kind(param, source);
1860
1861        let hir_id = self.lower_node_id(param.id);
1862        self.lower_attrs(hir_id, &param.attrs, param.span());
1863        hir::GenericParam {
1864            hir_id,
1865            def_id: self.local_def_id(param.id),
1866            name,
1867            span: self.lower_span(param.span()),
1868            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
1869            kind,
1870            colon_span: param.colon_span.map(|s| self.lower_span(s)),
1871            source,
1872        }
1873    }
1874
1875    fn lower_generic_param_kind(
1876        &mut self,
1877        param: &GenericParam,
1878        source: hir::GenericParamSource,
1879    ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1880        match &param.kind {
1881            GenericParamKind::Lifetime => {
1882                // AST resolution emitted an error on those parameters, so we lower them using
1883                // `ParamName::Error`.
1884                let ident = self.lower_ident(param.ident);
1885                let param_name =
1886                    if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1887                        ParamName::Error(ident)
1888                    } else {
1889                        ParamName::Plain(ident)
1890                    };
1891                let kind =
1892                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1893
1894                (param_name, kind)
1895            }
1896            GenericParamKind::Type { default, .. } => {
1897                // Not only do we deny type param defaults in binders but we also map them to `None`
1898                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1899                let default = default
1900                    .as_ref()
1901                    .filter(|_| match source {
1902                        hir::GenericParamSource::Generics => true,
1903                        hir::GenericParamSource::Binder => {
1904                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1905                                span: param.span(),
1906                            });
1907
1908                            false
1909                        }
1910                    })
1911                    .map(|def| {
1912                        self.lower_ty(
1913                            def,
1914                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1915                        )
1916                    });
1917
1918                let kind = hir::GenericParamKind::Type { default, synthetic: false };
1919
1920                (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1921            }
1922            GenericParamKind::Const { ty, kw_span: _, default } => {
1923                let ty = self
1924                    .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1925
1926                // Not only do we deny const param defaults in binders but we also map them to `None`
1927                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1928                let default = default
1929                    .as_ref()
1930                    .filter(|_| match source {
1931                        hir::GenericParamSource::Generics => true,
1932                        hir::GenericParamSource::Binder => {
1933                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1934                                span: param.span(),
1935                            });
1936
1937                            false
1938                        }
1939                    })
1940                    .map(|def| self.lower_anon_const_to_const_arg(def));
1941
1942                (
1943                    hir::ParamName::Plain(self.lower_ident(param.ident)),
1944                    hir::GenericParamKind::Const { ty, default, synthetic: false },
1945                )
1946            }
1947        }
1948    }
1949
1950    fn lower_trait_ref(
1951        &mut self,
1952        modifiers: ast::TraitBoundModifiers,
1953        p: &TraitRef,
1954        itctx: ImplTraitContext,
1955    ) -> hir::TraitRef<'hir> {
1956        let path = match self.lower_qpath(
1957            p.ref_id,
1958            &None,
1959            &p.path,
1960            ParamMode::Explicit,
1961            AllowReturnTypeNotation::No,
1962            itctx,
1963            Some(modifiers),
1964        ) {
1965            hir::QPath::Resolved(None, path) => path,
1966            qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
1967        };
1968        hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1969    }
1970
1971    #[instrument(level = "debug", skip(self))]
1972    fn lower_poly_trait_ref(
1973        &mut self,
1974        p: &PolyTraitRef,
1975        itctx: ImplTraitContext,
1976    ) -> hir::PolyTraitRef<'hir> {
1977        let bound_generic_params =
1978            self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
1979        let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
1980        let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
1981        hir::PolyTraitRef {
1982            bound_generic_params,
1983            modifiers,
1984            trait_ref,
1985            span: self.lower_span(p.span),
1986        }
1987    }
1988
1989    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1990        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1991    }
1992
1993    #[instrument(level = "debug", skip(self), ret)]
1994    fn lower_param_bounds(
1995        &mut self,
1996        bounds: &[GenericBound],
1997        itctx: ImplTraitContext,
1998    ) -> hir::GenericBounds<'hir> {
1999        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2000    }
2001
2002    fn lower_param_bounds_mut(
2003        &mut self,
2004        bounds: &[GenericBound],
2005        itctx: ImplTraitContext,
2006    ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2007        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2008    }
2009
2010    #[instrument(level = "debug", skip(self), ret)]
2011    fn lower_universal_param_and_bounds(
2012        &mut self,
2013        node_id: NodeId,
2014        span: Span,
2015        ident: Ident,
2016        bounds: &[GenericBound],
2017    ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2018        // Add a definition for the in-band `Param`.
2019        let def_id = self.local_def_id(node_id);
2020        let span = self.lower_span(span);
2021
2022        // Set the name to `impl Bound1 + Bound2`.
2023        let param = hir::GenericParam {
2024            hir_id: self.lower_node_id(node_id),
2025            def_id,
2026            name: ParamName::Plain(self.lower_ident(ident)),
2027            pure_wrt_drop: false,
2028            span,
2029            kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2030            colon_span: None,
2031            source: hir::GenericParamSource::Generics,
2032        };
2033
2034        let preds = self.lower_generic_bound_predicate(
2035            ident,
2036            node_id,
2037            &GenericParamKind::Type { default: None },
2038            bounds,
2039            /* colon_span */ None,
2040            span,
2041            ImplTraitContext::Universal,
2042            hir::PredicateOrigin::ImplTrait,
2043        );
2044
2045        let hir_id = self.next_id();
2046        let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2047        let ty = hir::TyKind::Path(hir::QPath::Resolved(
2048            None,
2049            self.arena.alloc(hir::Path {
2050                span,
2051                res,
2052                segments:
2053                    arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2054            }),
2055        ));
2056
2057        (param, preds, ty)
2058    }
2059
2060    /// Lowers a block directly to an expression, presuming that it
2061    /// has no attributes and is not targeted by a `break`.
2062    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2063        let block = self.lower_block(b, false);
2064        self.expr_block(block)
2065    }
2066
2067    fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2068        // We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
2069        // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
2070        match c.value.peel_parens().kind {
2071            ExprKind::Underscore => {
2072                if !self.tcx.features().generic_arg_infer() {
2073                    feature_err(
2074                        &self.tcx.sess,
2075                        sym::generic_arg_infer,
2076                        c.value.span,
2077                        fluent_generated::ast_lowering_underscore_array_length_unstable,
2078                    )
2079                    .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2080                }
2081                let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2082                self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2083            }
2084            _ => self.lower_anon_const_to_const_arg(c),
2085        }
2086    }
2087
2088    /// Used when lowering a type argument that turned out to actually be a const argument.
2089    ///
2090    /// Only use for that purpose since otherwise it will create a duplicate def.
2091    #[instrument(level = "debug", skip(self))]
2092    fn lower_const_path_to_const_arg(
2093        &mut self,
2094        path: &Path,
2095        res: Res<NodeId>,
2096        ty_id: NodeId,
2097        span: Span,
2098    ) -> &'hir hir::ConstArg<'hir> {
2099        let tcx = self.tcx;
2100
2101        let ct_kind = if path
2102            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2103            && (tcx.features().min_generic_const_args()
2104                || matches!(res, Res::Def(DefKind::ConstParam, _)))
2105        {
2106            let qpath = self.lower_qpath(
2107                ty_id,
2108                &None,
2109                path,
2110                ParamMode::Optional,
2111                AllowReturnTypeNotation::No,
2112                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2113                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2114                None,
2115            );
2116            hir::ConstArgKind::Path(qpath)
2117        } else {
2118            // Construct an AnonConst where the expr is the "ty"'s path.
2119            let node_id = self.next_node_id();
2120            let span = self.lower_span(span);
2121
2122            // Add a definition for the in-band const def.
2123            // We're lowering a const argument that was originally thought to be a type argument,
2124            // so the def collector didn't create the def ahead of time. That's why we have to do
2125            // it here.
2126            let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2127            let hir_id = self.lower_node_id(node_id);
2128
2129            let path_expr = Expr {
2130                id: ty_id,
2131                kind: ExprKind::Path(None, path.clone()),
2132                span,
2133                attrs: AttrVec::new(),
2134                tokens: None,
2135            };
2136
2137            let ct = self.with_new_scopes(span, |this| {
2138                self.arena.alloc(hir::AnonConst {
2139                    def_id,
2140                    hir_id,
2141                    body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2142                    span,
2143                })
2144            });
2145            hir::ConstArgKind::Anon(ct)
2146        };
2147
2148        self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2149    }
2150
2151    /// See [`hir::ConstArg`] for when to use this function vs
2152    /// [`Self::lower_anon_const_to_anon_const`].
2153    fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2154        self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2155    }
2156
2157    #[instrument(level = "debug", skip(self))]
2158    fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2159        let tcx = self.tcx;
2160        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
2161        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
2162        let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2163            && let [stmt] = block.stmts.as_slice()
2164            && let StmtKind::Expr(expr) = &stmt.kind
2165            && let ExprKind::Path(..) = &expr.kind
2166        {
2167            expr
2168        } else {
2169            &anon.value
2170        };
2171        let maybe_res =
2172            self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2173        if let ExprKind::Path(qself, path) = &expr.kind
2174            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2175            && (tcx.features().min_generic_const_args()
2176                || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2177        {
2178            let qpath = self.lower_qpath(
2179                expr.id,
2180                qself,
2181                path,
2182                ParamMode::Optional,
2183                AllowReturnTypeNotation::No,
2184                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2185                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2186                None,
2187            );
2188
2189            return ConstArg {
2190                hir_id: self.lower_node_id(anon.id),
2191                kind: hir::ConstArgKind::Path(qpath),
2192            };
2193        }
2194
2195        let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2196        ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2197    }
2198
2199    /// See [`hir::ConstArg`] for when to use this function vs
2200    /// [`Self::lower_anon_const_to_const_arg`].
2201    fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2202        self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2203            let def_id = this.local_def_id(c.id);
2204            let hir_id = this.lower_node_id(c.id);
2205            hir::AnonConst {
2206                def_id,
2207                hir_id,
2208                body: this.lower_const_body(c.value.span, Some(&c.value)),
2209                span: this.lower_span(c.value.span),
2210            }
2211        }))
2212    }
2213
2214    fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2215        match u {
2216            CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2217            UserProvided => hir::UnsafeSource::UserProvided,
2218        }
2219    }
2220
2221    fn lower_trait_bound_modifiers(
2222        &mut self,
2223        modifiers: TraitBoundModifiers,
2224    ) -> hir::TraitBoundModifiers {
2225        hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2226    }
2227
2228    // Helper methods for building HIR.
2229
2230    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2231        hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2232    }
2233
2234    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2235        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2236    }
2237
2238    fn stmt_let_pat(
2239        &mut self,
2240        attrs: Option<&'hir [hir::Attribute]>,
2241        span: Span,
2242        init: Option<&'hir hir::Expr<'hir>>,
2243        pat: &'hir hir::Pat<'hir>,
2244        source: hir::LocalSource,
2245    ) -> hir::Stmt<'hir> {
2246        let hir_id = self.next_id();
2247        if let Some(a) = attrs {
2248            debug_assert!(!a.is_empty());
2249            self.attrs.insert(hir_id.local_id, a);
2250        }
2251        let local = hir::LetStmt {
2252            super_: None,
2253            hir_id,
2254            init,
2255            pat,
2256            els: None,
2257            source,
2258            span: self.lower_span(span),
2259            ty: None,
2260        };
2261        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2262    }
2263
2264    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2265        self.block_all(expr.span, &[], Some(expr))
2266    }
2267
2268    fn block_all(
2269        &mut self,
2270        span: Span,
2271        stmts: &'hir [hir::Stmt<'hir>],
2272        expr: Option<&'hir hir::Expr<'hir>>,
2273    ) -> &'hir hir::Block<'hir> {
2274        let blk = hir::Block {
2275            stmts,
2276            expr,
2277            hir_id: self.next_id(),
2278            rules: hir::BlockCheckMode::DefaultBlock,
2279            span: self.lower_span(span),
2280            targeted_by_break: false,
2281        };
2282        self.arena.alloc(blk)
2283    }
2284
2285    fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2286        let field = self.single_pat_field(span, pat);
2287        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2288    }
2289
2290    fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2291        let field = self.single_pat_field(span, pat);
2292        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2293    }
2294
2295    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2296        let field = self.single_pat_field(span, pat);
2297        self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2298    }
2299
2300    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2301        self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2302    }
2303
2304    fn single_pat_field(
2305        &mut self,
2306        span: Span,
2307        pat: &'hir hir::Pat<'hir>,
2308    ) -> &'hir [hir::PatField<'hir>] {
2309        let field = hir::PatField {
2310            hir_id: self.next_id(),
2311            ident: Ident::new(sym::integer(0), self.lower_span(span)),
2312            is_shorthand: false,
2313            pat,
2314            span: self.lower_span(span),
2315        };
2316        arena_vec![self; field]
2317    }
2318
2319    fn pat_lang_item_variant(
2320        &mut self,
2321        span: Span,
2322        lang_item: hir::LangItem,
2323        fields: &'hir [hir::PatField<'hir>],
2324    ) -> &'hir hir::Pat<'hir> {
2325        let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2326        self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2327    }
2328
2329    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2330        self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2331    }
2332
2333    fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2334        self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2335    }
2336
2337    fn pat_ident_binding_mode(
2338        &mut self,
2339        span: Span,
2340        ident: Ident,
2341        bm: hir::BindingMode,
2342    ) -> (&'hir hir::Pat<'hir>, HirId) {
2343        let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2344        (self.arena.alloc(pat), hir_id)
2345    }
2346
2347    fn pat_ident_binding_mode_mut(
2348        &mut self,
2349        span: Span,
2350        ident: Ident,
2351        bm: hir::BindingMode,
2352    ) -> (hir::Pat<'hir>, HirId) {
2353        let hir_id = self.next_id();
2354
2355        (
2356            hir::Pat {
2357                hir_id,
2358                kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2359                span: self.lower_span(span),
2360                default_binding_modes: true,
2361            },
2362            hir_id,
2363        )
2364    }
2365
2366    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2367        self.arena.alloc(hir::Pat {
2368            hir_id: self.next_id(),
2369            kind,
2370            span: self.lower_span(span),
2371            default_binding_modes: true,
2372        })
2373    }
2374
2375    fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2376        hir::Pat {
2377            hir_id: self.next_id(),
2378            kind,
2379            span: self.lower_span(span),
2380            default_binding_modes: false,
2381        }
2382    }
2383
2384    fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2385        let kind = match qpath {
2386            hir::QPath::Resolved(None, path) => {
2387                // Turn trait object paths into `TyKind::TraitObject` instead.
2388                match path.res {
2389                    Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2390                        let principal = hir::PolyTraitRef {
2391                            bound_generic_params: &[],
2392                            modifiers: hir::TraitBoundModifiers::NONE,
2393                            trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2394                            span: self.lower_span(span),
2395                        };
2396
2397                        // The original ID is taken by the `PolyTraitRef`,
2398                        // so the `Ty` itself needs a different one.
2399                        hir_id = self.next_id();
2400                        hir::TyKind::TraitObject(
2401                            arena_vec![self; principal],
2402                            TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2403                        )
2404                    }
2405                    _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2406                }
2407            }
2408            _ => hir::TyKind::Path(qpath),
2409        };
2410
2411        hir::Ty { hir_id, kind, span: self.lower_span(span) }
2412    }
2413
2414    /// Invoked to create the lifetime argument(s) for an elided trait object
2415    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2416    /// when the bound is written, even if it is written with `'_` like in
2417    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2418    fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2419        let r = hir::Lifetime::new(
2420            self.next_id(),
2421            Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2422            hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2423            LifetimeSource::Other,
2424            LifetimeSyntax::Hidden,
2425        );
2426        debug!("elided_dyn_bound: r={:?}", r);
2427        self.arena.alloc(r)
2428    }
2429}
2430
2431/// Helper struct for the delayed construction of [`hir::GenericArgs`].
2432struct GenericArgsCtor<'hir> {
2433    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2434    constraints: &'hir [hir::AssocItemConstraint<'hir>],
2435    parenthesized: hir::GenericArgsParentheses,
2436    span: Span,
2437}
2438
2439impl<'hir> GenericArgsCtor<'hir> {
2440    fn is_empty(&self) -> bool {
2441        self.args.is_empty()
2442            && self.constraints.is_empty()
2443            && self.parenthesized == hir::GenericArgsParentheses::No
2444    }
2445
2446    fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2447        let ga = hir::GenericArgs {
2448            args: this.arena.alloc_from_iter(self.args),
2449            constraints: self.constraints,
2450            parenthesized: self.parenthesized,
2451            span_ext: this.lower_span(self.span),
2452        };
2453        this.arena.alloc(ga)
2454    }
2455}