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