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