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;
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    let mut lowerer = item::ItemLowerer {
448        tcx,
449        resolver: &mut resolver,
450        ast_index: &ast_index,
451        owners: &mut owners,
452    };
453    for def_id in ast_index.indices() {
454        lowerer.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) -> PerNS<Option<Res>> {
709        let per_ns = self.resolver.get_import_res(id);
710        let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));
711        if per_ns.is_empty() {
712            // Propagate the error to all namespaces, just to be sure.
713            self.dcx().span_delayed_bug(span, "no resolution for an import");
714            let err = Some(Res::Err);
715            return PerNS { type_ns: err, value_ns: err, macro_ns: err };
716        }
717        per_ns
718    }
719
720    fn make_lang_item_qpath(
721        &mut self,
722        lang_item: hir::LangItem,
723        span: Span,
724        args: Option<&'hir hir::GenericArgs<'hir>>,
725    ) -> hir::QPath<'hir> {
726        hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
727    }
728
729    fn make_lang_item_path(
730        &mut self,
731        lang_item: hir::LangItem,
732        span: Span,
733        args: Option<&'hir hir::GenericArgs<'hir>>,
734    ) -> &'hir hir::Path<'hir> {
735        let def_id = self.tcx.require_lang_item(lang_item, span);
736        let def_kind = self.tcx.def_kind(def_id);
737        let res = Res::Def(def_kind, def_id);
738        self.arena.alloc(hir::Path {
739            span,
740            res,
741            segments: self.arena.alloc_from_iter([hir::PathSegment {
742                ident: Ident::new(lang_item.name(), span),
743                hir_id: self.next_id(),
744                res,
745                args,
746                infer_args: args.is_none(),
747            }]),
748        })
749    }
750
751    /// Reuses the span but adds information like the kind of the desugaring and features that are
752    /// allowed inside this span.
753    fn mark_span_with_reason(
754        &self,
755        reason: DesugaringKind,
756        span: Span,
757        allow_internal_unstable: Option<Arc<[Symbol]>>,
758    ) -> Span {
759        self.tcx.with_stable_hashing_context(|hcx| {
760            span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)
761        })
762    }
763
764    /// Intercept all spans entering HIR.
765    /// Mark a span as relative to the current owning item.
766    fn lower_span(&self, span: Span) -> Span {
767        if self.tcx.sess.opts.incremental.is_some() {
768            span.with_parent(Some(self.current_hir_id_owner.def_id))
769        } else {
770            // Do not make spans relative when not using incremental compilation.
771            span
772        }
773    }
774
775    fn lower_ident(&self, ident: Ident) -> Ident {
776        Ident::new(ident.name, self.lower_span(ident.span))
777    }
778
779    /// Converts a lifetime into a new generic parameter.
780    #[instrument(level = "debug", skip(self))]
781    fn lifetime_res_to_generic_param(
782        &mut self,
783        ident: Ident,
784        node_id: NodeId,
785        res: LifetimeRes,
786        source: hir::GenericParamSource,
787    ) -> Option<hir::GenericParam<'hir>> {
788        let (name, kind) = match res {
789            LifetimeRes::Param { .. } => {
790                (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
791            }
792            LifetimeRes::Fresh { param, kind, .. } => {
793                // Late resolution delegates to us the creation of the `LocalDefId`.
794                let _def_id = self.create_def(
795                    param,
796                    Some(kw::UnderscoreLifetime),
797                    DefKind::LifetimeParam,
798                    ident.span,
799                );
800                debug!(?_def_id);
801
802                (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
803            }
804            LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
805            res => panic!(
806                "Unexpected lifetime resolution {:?} for {:?} at {:?}",
807                res, ident, ident.span
808            ),
809        };
810        let hir_id = self.lower_node_id(node_id);
811        let def_id = self.local_def_id(node_id);
812        Some(hir::GenericParam {
813            hir_id,
814            def_id,
815            name,
816            span: self.lower_span(ident.span),
817            pure_wrt_drop: false,
818            kind: hir::GenericParamKind::Lifetime { kind },
819            colon_span: None,
820            source,
821        })
822    }
823
824    /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR
825    /// nodes. The returned list includes any "extra" lifetime parameters that were added by the
826    /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
827    /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
828    /// parameters will be successful.
829    #[instrument(level = "debug", skip(self))]
830    #[inline]
831    fn lower_lifetime_binder(
832        &mut self,
833        binder: NodeId,
834        generic_params: &[GenericParam],
835    ) -> &'hir [hir::GenericParam<'hir>] {
836        let mut generic_params: Vec<_> = self
837            .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
838            .collect();
839        let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
840        debug!(?extra_lifetimes);
841        generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
842            self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
843        }));
844        let generic_params = self.arena.alloc_from_iter(generic_params);
845        debug!(?generic_params);
846
847        generic_params
848    }
849
850    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
851        let was_in_dyn_type = self.is_in_dyn_type;
852        self.is_in_dyn_type = in_scope;
853
854        let result = f(self);
855
856        self.is_in_dyn_type = was_in_dyn_type;
857
858        result
859    }
860
861    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
862        let current_item = self.current_item;
863        self.current_item = Some(scope_span);
864
865        let was_in_loop_condition = self.is_in_loop_condition;
866        self.is_in_loop_condition = false;
867
868        let old_contract = self.contract_ensures.take();
869
870        let catch_scope = self.catch_scope.take();
871        let loop_scope = self.loop_scope.take();
872        let ret = f(self);
873        self.catch_scope = catch_scope;
874        self.loop_scope = loop_scope;
875
876        self.contract_ensures = old_contract;
877
878        self.is_in_loop_condition = was_in_loop_condition;
879
880        self.current_item = current_item;
881
882        ret
883    }
884
885    fn lower_attrs(
886        &mut self,
887        id: HirId,
888        attrs: &[Attribute],
889        target_span: Span,
890    ) -> &'hir [hir::Attribute] {
891        if attrs.is_empty() {
892            &[]
893        } else {
894            let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span));
895
896            debug_assert_eq!(id.owner, self.current_hir_id_owner);
897            let ret = self.arena.alloc_from_iter(lowered_attrs);
898
899            // this is possible if an item contained syntactical attribute,
900            // but none of them parse successfully or all of them were ignored
901            // for not being built-in attributes at all. They could be remaining
902            // unexpanded attributes used as markers in proc-macro derives for example.
903            // This will have emitted some diagnostics for the misparse, but will then
904            // not emit the attribute making the list empty.
905            if ret.is_empty() {
906                &[]
907            } else {
908                self.attrs.insert(id.local_id, ret);
909                ret
910            }
911        }
912    }
913
914    fn lower_attrs_vec(&self, attrs: &[Attribute], target_span: Span) -> Vec<hir::Attribute> {
915        self.attribute_parser
916            .parse_attribute_list(attrs, target_span, OmitDoc::Lower, |s| self.lower_span(s))
917    }
918
919    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
920        debug_assert_eq!(id.owner, self.current_hir_id_owner);
921        debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
922        if let Some(&a) = self.attrs.get(&target_id.local_id) {
923            debug_assert!(!a.is_empty());
924            self.attrs.insert(id.local_id, a);
925        }
926    }
927
928    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
929        args.clone()
930    }
931
932    /// Lower an associated item constraint.
933    #[instrument(level = "debug", skip_all)]
934    fn lower_assoc_item_constraint(
935        &mut self,
936        constraint: &AssocItemConstraint,
937        itctx: ImplTraitContext,
938    ) -> hir::AssocItemConstraint<'hir> {
939        debug!(?constraint, ?itctx);
940        // Lower the generic arguments for the associated item.
941        let gen_args = if let Some(gen_args) = &constraint.gen_args {
942            let gen_args_ctor = match gen_args {
943                GenericArgs::AngleBracketed(data) => {
944                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
945                }
946                GenericArgs::Parenthesized(data) => {
947                    if let Some(first_char) = constraint.ident.as_str().chars().next()
948                        && first_char.is_ascii_lowercase()
949                    {
950                        let err = match (&data.inputs[..], &data.output) {
951                            ([_, ..], FnRetTy::Default(_)) => {
952                                errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
953                            }
954                            ([], FnRetTy::Default(_)) => {
955                                errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
956                            }
957                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.
958                            (_, FnRetTy::Ty(ty)) => {
959                                let span = data.inputs_span.shrink_to_hi().to(ty.span);
960                                errors::BadReturnTypeNotation::Output {
961                                    span,
962                                    suggestion: errors::RTNSuggestion {
963                                        output: span,
964                                        input: data.inputs_span,
965                                    },
966                                }
967                            }
968                        };
969                        let mut err = self.dcx().create_err(err);
970                        if !self.tcx.features().return_type_notation()
971                            && self.tcx.sess.is_nightly_build()
972                        {
973                            add_feature_diagnostics(
974                                &mut err,
975                                &self.tcx.sess,
976                                sym::return_type_notation,
977                            );
978                        }
979                        err.emit();
980                        GenericArgsCtor {
981                            args: Default::default(),
982                            constraints: &[],
983                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
984                            span: data.span,
985                        }
986                    } else {
987                        self.emit_bad_parenthesized_trait_in_assoc_ty(data);
988                        // FIXME(return_type_notation): we could issue a feature error
989                        // if the parens are empty and there's no return type.
990                        self.lower_angle_bracketed_parameter_data(
991                            &data.as_angle_bracketed_args(),
992                            ParamMode::Explicit,
993                            itctx,
994                        )
995                        .0
996                    }
997                }
998                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
999                    args: Default::default(),
1000                    constraints: &[],
1001                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1002                    span: *span,
1003                },
1004            };
1005            gen_args_ctor.into_generic_args(self)
1006        } else {
1007            self.arena.alloc(hir::GenericArgs::none())
1008        };
1009        let kind = match &constraint.kind {
1010            AssocItemConstraintKind::Equality { term } => {
1011                let term = match term {
1012                    Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1013                    Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1014                };
1015                hir::AssocItemConstraintKind::Equality { term }
1016            }
1017            AssocItemConstraintKind::Bound { bounds } => {
1018                // Disallow ATB in dyn types
1019                if self.is_in_dyn_type {
1020                    let suggestion = match itctx {
1021                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1022                            let bound_end_span = constraint
1023                                .gen_args
1024                                .as_ref()
1025                                .map_or(constraint.ident.span, |args| args.span());
1026                            if bound_end_span.eq_ctxt(constraint.span) {
1027                                Some(self.tcx.sess.source_map().next_point(bound_end_span))
1028                            } else {
1029                                None
1030                            }
1031                        }
1032                        _ => None,
1033                    };
1034
1035                    let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1036                        span: constraint.span,
1037                        suggestion,
1038                    });
1039                    let err_ty =
1040                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1041                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1042                } else {
1043                    // Desugar `AssocTy: Bounds` into an assoc type binding where the
1044                    // later desugars into a trait predicate.
1045                    let bounds = self.lower_param_bounds(bounds, itctx);
1046
1047                    hir::AssocItemConstraintKind::Bound { bounds }
1048                }
1049            }
1050        };
1051
1052        hir::AssocItemConstraint {
1053            hir_id: self.lower_node_id(constraint.id),
1054            ident: self.lower_ident(constraint.ident),
1055            gen_args,
1056            kind,
1057            span: self.lower_span(constraint.span),
1058        }
1059    }
1060
1061    fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1062        // Suggest removing empty parentheses: "Trait()" -> "Trait"
1063        let sub = if data.inputs.is_empty() {
1064            let parentheses_span =
1065                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1066            AssocTyParenthesesSub::Empty { parentheses_span }
1067        }
1068        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1069        else {
1070            // Start of parameters to the 1st argument
1071            let open_param = data.inputs_span.shrink_to_lo().to(data
1072                .inputs
1073                .first()
1074                .unwrap()
1075                .span
1076                .shrink_to_lo());
1077            // End of last argument to end of parameters
1078            let close_param =
1079                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1080            AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1081        };
1082        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1083    }
1084
1085    #[instrument(level = "debug", skip(self))]
1086    fn lower_generic_arg(
1087        &mut self,
1088        arg: &ast::GenericArg,
1089        itctx: ImplTraitContext,
1090    ) -> hir::GenericArg<'hir> {
1091        match arg {
1092            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1093                lt,
1094                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1095                lt.ident.into(),
1096            )),
1097            ast::GenericArg::Type(ty) => {
1098                // We cannot just match on `TyKind::Infer` as `(_)` is represented as
1099                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`
1100                if ty.is_maybe_parenthesised_infer() {
1101                    return GenericArg::Infer(hir::InferArg {
1102                        hir_id: self.lower_node_id(ty.id),
1103                        span: self.lower_span(ty.span),
1104                    });
1105                }
1106
1107                match &ty.kind {
1108                    // We parse const arguments as path types as we cannot distinguish them during
1109                    // parsing. We try to resolve that ambiguity by attempting resolution in both the
1110                    // type and value namespaces. If we resolved the path in the value namespace, we
1111                    // transform it into a generic const argument.
1112                    //
1113                    // FIXME: Should we be handling `(PATH_TO_CONST)`?
1114                    TyKind::Path(None, path) => {
1115                        if let Some(res) = self
1116                            .resolver
1117                            .get_partial_res(ty.id)
1118                            .and_then(|partial_res| partial_res.full_res())
1119                        {
1120                            if !res.matches_ns(Namespace::TypeNS)
1121                                && path.is_potential_trivial_const_arg(false)
1122                            {
1123                                debug!(
1124                                    "lower_generic_arg: Lowering type argument as const argument: {:?}",
1125                                    ty,
1126                                );
1127
1128                                let ct =
1129                                    self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1130                                return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1131                            }
1132                        }
1133                    }
1134                    _ => {}
1135                }
1136                GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1137            }
1138            ast::GenericArg::Const(ct) => {
1139                GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1140            }
1141        }
1142    }
1143
1144    #[instrument(level = "debug", skip(self))]
1145    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1146        self.arena.alloc(self.lower_ty_direct(t, itctx))
1147    }
1148
1149    fn lower_path_ty(
1150        &mut self,
1151        t: &Ty,
1152        qself: &Option<ptr::P<QSelf>>,
1153        path: &Path,
1154        param_mode: ParamMode,
1155        itctx: ImplTraitContext,
1156    ) -> hir::Ty<'hir> {
1157        // Check whether we should interpret this as a bare trait object.
1158        // This check mirrors the one in late resolution. We only introduce this special case in
1159        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.
1160        // The other cases when a qpath should be opportunistically made a trait object are handled
1161        // by `ty_path`.
1162        if qself.is_none()
1163            && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1164            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1165        {
1166            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1167                let bound = this.lower_poly_trait_ref(
1168                    &PolyTraitRef {
1169                        bound_generic_params: ThinVec::new(),
1170                        modifiers: TraitBoundModifiers::NONE,
1171                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1172                        span: t.span,
1173                    },
1174                    itctx,
1175                );
1176                let bounds = this.arena.alloc_from_iter([bound]);
1177                let lifetime_bound = this.elided_dyn_bound(t.span);
1178                (bounds, lifetime_bound)
1179            });
1180            let kind = hir::TyKind::TraitObject(
1181                bounds,
1182                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1183            );
1184            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1185        }
1186
1187        let id = self.lower_node_id(t.id);
1188        let qpath = self.lower_qpath(
1189            t.id,
1190            qself,
1191            path,
1192            param_mode,
1193            AllowReturnTypeNotation::Yes,
1194            itctx,
1195            None,
1196        );
1197        self.ty_path(id, t.span, qpath)
1198    }
1199
1200    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1201        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1202    }
1203
1204    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1205        self.ty(span, hir::TyKind::Tup(tys))
1206    }
1207
1208    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1209        let kind = match &t.kind {
1210            TyKind::Infer => hir::TyKind::Infer(()),
1211            TyKind::Err(guar) => hir::TyKind::Err(*guar),
1212            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1213            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1214            TyKind::Ref(region, mt) => {
1215                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1216                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1217            }
1218            TyKind::PinnedRef(region, mt) => {
1219                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1220                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1221                let span = self.lower_span(t.span);
1222                let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1223                let args = self.arena.alloc(hir::GenericArgs {
1224                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1225                    constraints: &[],
1226                    parenthesized: hir::GenericArgsParentheses::No,
1227                    span_ext: span,
1228                });
1229                let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1230                hir::TyKind::Path(path)
1231            }
1232            TyKind::BareFn(f) => {
1233                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1234                hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
1235                    generic_params,
1236                    safety: self.lower_safety(f.safety, hir::Safety::Safe),
1237                    abi: self.lower_extern(f.ext),
1238                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1239                    param_idents: self.lower_fn_params_to_idents(&f.decl),
1240                }))
1241            }
1242            TyKind::UnsafeBinder(f) => {
1243                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1244                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1245                    generic_params,
1246                    inner_ty: self.lower_ty(&f.inner_ty, itctx),
1247                }))
1248            }
1249            TyKind::Never => hir::TyKind::Never,
1250            TyKind::Tup(tys) => hir::TyKind::Tup(
1251                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1252            ),
1253            TyKind::Paren(ty) => {
1254                return self.lower_ty_direct(ty, itctx);
1255            }
1256            TyKind::Path(qself, path) => {
1257                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1258            }
1259            TyKind::ImplicitSelf => {
1260                let hir_id = self.next_id();
1261                let res = self.expect_full_res(t.id);
1262                let res = self.lower_res(res);
1263                hir::TyKind::Path(hir::QPath::Resolved(
1264                    None,
1265                    self.arena.alloc(hir::Path {
1266                        res,
1267                        segments: arena_vec![self; hir::PathSegment::new(
1268                            Ident::with_dummy_span(kw::SelfUpper),
1269                            hir_id,
1270                            res
1271                        )],
1272                        span: self.lower_span(t.span),
1273                    }),
1274                ))
1275            }
1276            TyKind::Array(ty, length) => hir::TyKind::Array(
1277                self.lower_ty(ty, itctx),
1278                self.lower_array_length_to_const_arg(length),
1279            ),
1280            TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1281            TyKind::TraitObject(bounds, kind) => {
1282                let mut lifetime_bound = None;
1283                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1284                    let bounds =
1285                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1286                            // We can safely ignore constness here since AST validation
1287                            // takes care of rejecting invalid modifier combinations and
1288                            // const trait bounds in trait object types.
1289                            GenericBound::Trait(ty) => {
1290                                let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1291                                Some(trait_ref)
1292                            }
1293                            GenericBound::Outlives(lifetime) => {
1294                                if lifetime_bound.is_none() {
1295                                    lifetime_bound = Some(this.lower_lifetime(
1296                                        lifetime,
1297                                        LifetimeSource::Other,
1298                                        lifetime.ident.into(),
1299                                    ));
1300                                }
1301                                None
1302                            }
1303                            // Ignore `use` syntax since that is not valid in objects.
1304                            GenericBound::Use(_, span) => {
1305                                this.dcx()
1306                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");
1307                                None
1308                            }
1309                        }));
1310                    let lifetime_bound =
1311                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1312                    (bounds, lifetime_bound)
1313                });
1314                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1315            }
1316            TyKind::ImplTrait(def_node_id, bounds) => {
1317                let span = t.span;
1318                match itctx {
1319                    ImplTraitContext::OpaqueTy { origin } => {
1320                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1321                    }
1322                    ImplTraitContext::Universal => {
1323                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1324                            ast::GenericBound::Use(_, span) => Some(span),
1325                            _ => None,
1326                        }) {
1327                            self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1328                        }
1329
1330                        let def_id = self.local_def_id(*def_node_id);
1331                        let name = self.tcx.item_name(def_id.to_def_id());
1332                        let ident = Ident::new(name, span);
1333                        let (param, bounds, path) = self.lower_universal_param_and_bounds(
1334                            *def_node_id,
1335                            span,
1336                            ident,
1337                            bounds,
1338                        );
1339                        self.impl_trait_defs.push(param);
1340                        if let Some(bounds) = bounds {
1341                            self.impl_trait_bounds.push(bounds);
1342                        }
1343                        path
1344                    }
1345                    ImplTraitContext::InBinding => {
1346                        hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1347                    }
1348                    ImplTraitContext::FeatureGated(position, feature) => {
1349                        let guar = self
1350                            .tcx
1351                            .sess
1352                            .create_feature_err(
1353                                MisplacedImplTrait {
1354                                    span: t.span,
1355                                    position: DiagArgFromDisplay(&position),
1356                                },
1357                                feature,
1358                            )
1359                            .emit();
1360                        hir::TyKind::Err(guar)
1361                    }
1362                    ImplTraitContext::Disallowed(position) => {
1363                        let guar = self.dcx().emit_err(MisplacedImplTrait {
1364                            span: t.span,
1365                            position: DiagArgFromDisplay(&position),
1366                        });
1367                        hir::TyKind::Err(guar)
1368                    }
1369                }
1370            }
1371            TyKind::Pat(ty, pat) => {
1372                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1373            }
1374            TyKind::MacCall(_) => {
1375                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1376            }
1377            TyKind::CVarArgs => {
1378                let guar = self.dcx().span_delayed_bug(
1379                    t.span,
1380                    "`TyKind::CVarArgs` should have been handled elsewhere",
1381                );
1382                hir::TyKind::Err(guar)
1383            }
1384            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1385        };
1386
1387        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1388    }
1389
1390    fn lower_ty_direct_lifetime(
1391        &mut self,
1392        t: &Ty,
1393        region: Option<Lifetime>,
1394    ) -> &'hir hir::Lifetime {
1395        let (region, syntax) = match region {
1396            Some(region) => (region, region.ident.into()),
1397
1398            None => {
1399                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1400                    self.resolver.get_lifetime_res(t.id)
1401                {
1402                    debug_assert_eq!(start.plus(1), end);
1403                    start
1404                } else {
1405                    self.next_node_id()
1406                };
1407                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1408                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1409                (region, LifetimeSyntax::Implicit)
1410            }
1411        };
1412        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
1413    }
1414
1415    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1416    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1417    /// HIR type that references the TAIT.
1418    ///
1419    /// Given a function definition like:
1420    ///
1421    /// ```rust
1422    /// use std::fmt::Debug;
1423    ///
1424    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1425    ///     x
1426    /// }
1427    /// ```
1428    ///
1429    /// we will create a TAIT definition in the HIR like
1430    ///
1431    /// ```rust,ignore (pseudo-Rust)
1432    /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1433    /// ```
1434    ///
1435    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1436    ///
1437    /// ```rust,ignore (pseudo-Rust)
1438    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1439    /// ```
1440    ///
1441    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1442    /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1443    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1444    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1445    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1446    #[instrument(level = "debug", skip(self), ret)]
1447    fn lower_opaque_impl_trait(
1448        &mut self,
1449        span: Span,
1450        origin: hir::OpaqueTyOrigin<LocalDefId>,
1451        opaque_ty_node_id: NodeId,
1452        bounds: &GenericBounds,
1453        itctx: ImplTraitContext,
1454    ) -> hir::TyKind<'hir> {
1455        // Make sure we know that some funky desugaring has been going on here.
1456        // This is a first: there is code in other places like for loop
1457        // desugaring that explicitly states that we don't want to track that.
1458        // Not tracking it makes lints in rustc and clippy very fragile, as
1459        // frequently opened issues show.
1460        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1461
1462        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1463            this.lower_param_bounds(bounds, itctx)
1464        })
1465    }
1466
1467    fn lower_opaque_inner(
1468        &mut self,
1469        opaque_ty_node_id: NodeId,
1470        origin: hir::OpaqueTyOrigin<LocalDefId>,
1471        opaque_ty_span: Span,
1472        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1473    ) -> hir::TyKind<'hir> {
1474        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1475        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1476        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1477
1478        let bounds = lower_item_bounds(self);
1479        let opaque_ty_def = hir::OpaqueTy {
1480            hir_id: opaque_ty_hir_id,
1481            def_id: opaque_ty_def_id,
1482            bounds,
1483            origin,
1484            span: self.lower_span(opaque_ty_span),
1485        };
1486        let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1487
1488        hir::TyKind::OpaqueDef(opaque_ty_def)
1489    }
1490
1491    fn lower_precise_capturing_args(
1492        &mut self,
1493        precise_capturing_args: &[PreciseCapturingArg],
1494    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1495        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1496            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1497                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1498            ),
1499            PreciseCapturingArg::Arg(path, id) => {
1500                let [segment] = path.segments.as_slice() else {
1501                    panic!();
1502                };
1503                let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1504                    partial_res.full_res().expect("no partial res expected for precise capture arg")
1505                });
1506                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1507                    hir_id: self.lower_node_id(*id),
1508                    ident: self.lower_ident(segment.ident),
1509                    res: self.lower_res(res),
1510                })
1511            }
1512        }))
1513    }
1514
1515    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1516        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1517            PatKind::Missing => None,
1518            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1519            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1520            _ => {
1521                self.dcx().span_delayed_bug(
1522                    param.pat.span,
1523                    "non-missing/ident/wild param pat must trigger an error",
1524                );
1525                None
1526            }
1527        }))
1528    }
1529
1530    /// Lowers a function declaration.
1531    ///
1532    /// `decl`: the unlowered (AST) function declaration.
1533    ///
1534    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given
1535    /// `NodeId`.
1536    ///
1537    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is
1538    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.
1539    #[instrument(level = "debug", skip(self))]
1540    fn lower_fn_decl(
1541        &mut self,
1542        decl: &FnDecl,
1543        fn_node_id: NodeId,
1544        fn_span: Span,
1545        kind: FnDeclKind,
1546        coro: Option<CoroutineKind>,
1547    ) -> &'hir hir::FnDecl<'hir> {
1548        let c_variadic = decl.c_variadic();
1549
1550        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1551        // as they are not explicit in HIR/Ty function signatures.
1552        // (instead, the `c_variadic` flag is set to `true`)
1553        let mut inputs = &decl.inputs[..];
1554        if c_variadic {
1555            inputs = &inputs[..inputs.len() - 1];
1556        }
1557        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1558            let itctx = match kind {
1559                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1560                    ImplTraitContext::Universal
1561                }
1562                FnDeclKind::ExternFn => {
1563                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1564                }
1565                FnDeclKind::Closure => {
1566                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1567                }
1568                FnDeclKind::Pointer => {
1569                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1570                }
1571            };
1572            self.lower_ty_direct(&param.ty, itctx)
1573        }));
1574
1575        let output = match coro {
1576            Some(coro) => {
1577                let fn_def_id = self.local_def_id(fn_node_id);
1578                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1579            }
1580            None => match &decl.output {
1581                FnRetTy::Ty(ty) => {
1582                    let itctx = match kind {
1583                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1584                            origin: hir::OpaqueTyOrigin::FnReturn {
1585                                parent: self.local_def_id(fn_node_id),
1586                                in_trait_or_impl: None,
1587                            },
1588                        },
1589                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1590                            origin: hir::OpaqueTyOrigin::FnReturn {
1591                                parent: self.local_def_id(fn_node_id),
1592                                in_trait_or_impl: Some(hir::RpitContext::Trait),
1593                            },
1594                        },
1595                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1596                            origin: hir::OpaqueTyOrigin::FnReturn {
1597                                parent: self.local_def_id(fn_node_id),
1598                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1599                            },
1600                        },
1601                        FnDeclKind::ExternFn => {
1602                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1603                        }
1604                        FnDeclKind::Closure => {
1605                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1606                        }
1607                        FnDeclKind::Pointer => {
1608                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1609                        }
1610                    };
1611                    hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1612                }
1613                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1614            },
1615        };
1616
1617        self.arena.alloc(hir::FnDecl {
1618            inputs,
1619            output,
1620            c_variadic,
1621            lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1622            implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1623                let is_mutable_pat = matches!(
1624                    arg.pat.kind,
1625                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1626                );
1627
1628                match &arg.ty.kind {
1629                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1630                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1631                    // Given we are only considering `ImplicitSelf` types, we needn't consider
1632                    // the case where we have a mutable pattern to a reference as that would
1633                    // no longer be an `ImplicitSelf`.
1634                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1635                        if mt.ty.kind.is_implicit_self() =>
1636                    {
1637                        match mt.mutbl {
1638                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1639                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1640                        }
1641                    }
1642                    _ => hir::ImplicitSelfKind::None,
1643                }
1644            }),
1645        })
1646    }
1647
1648    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1649    // combined with the following definition of `OpaqueTy`:
1650    //
1651    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1652    //
1653    // `output`: unlowered output type (`T` in `-> T`)
1654    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)
1655    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1656    #[instrument(level = "debug", skip(self))]
1657    fn lower_coroutine_fn_ret_ty(
1658        &mut self,
1659        output: &FnRetTy,
1660        fn_def_id: LocalDefId,
1661        coro: CoroutineKind,
1662        fn_kind: FnDeclKind,
1663        fn_span: Span,
1664    ) -> hir::FnRetTy<'hir> {
1665        let span = self.lower_span(fn_span);
1666
1667        let (opaque_ty_node_id, allowed_features) = match coro {
1668            CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1669            CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1670            CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1671                (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1672            }
1673        };
1674
1675        let opaque_ty_span =
1676            self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1677
1678        let in_trait_or_impl = match fn_kind {
1679            FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1680            FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1681            FnDeclKind::Fn | FnDeclKind::Inherent => None,
1682            FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1683        };
1684
1685        let opaque_ty_ref = self.lower_opaque_inner(
1686            opaque_ty_node_id,
1687            hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1688            opaque_ty_span,
1689            |this| {
1690                let bound = this.lower_coroutine_fn_output_type_to_bound(
1691                    output,
1692                    coro,
1693                    opaque_ty_span,
1694                    ImplTraitContext::OpaqueTy {
1695                        origin: hir::OpaqueTyOrigin::FnReturn {
1696                            parent: fn_def_id,
1697                            in_trait_or_impl,
1698                        },
1699                    },
1700                );
1701                arena_vec![this; bound]
1702            },
1703        );
1704
1705        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1706        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1707    }
1708
1709    /// Transforms `-> T` into `Future<Output = T>`.
1710    fn lower_coroutine_fn_output_type_to_bound(
1711        &mut self,
1712        output: &FnRetTy,
1713        coro: CoroutineKind,
1714        opaque_ty_span: Span,
1715        itctx: ImplTraitContext,
1716    ) -> hir::GenericBound<'hir> {
1717        // Compute the `T` in `Future<Output = T>` from the return type.
1718        let output_ty = match output {
1719            FnRetTy::Ty(ty) => {
1720                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1721                // `impl Future` opaque type that `async fn` implicitly
1722                // generates.
1723                self.lower_ty(ty, itctx)
1724            }
1725            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1726        };
1727
1728        // "<$assoc_ty_name = T>"
1729        let (assoc_ty_name, trait_lang_item) = match coro {
1730            CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1731            CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1732            CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1733        };
1734
1735        let bound_args = self.arena.alloc(hir::GenericArgs {
1736            args: &[],
1737            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1738            parenthesized: hir::GenericArgsParentheses::No,
1739            span_ext: DUMMY_SP,
1740        });
1741
1742        hir::GenericBound::Trait(hir::PolyTraitRef {
1743            bound_generic_params: &[],
1744            modifiers: hir::TraitBoundModifiers::NONE,
1745            trait_ref: hir::TraitRef {
1746                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1747                hir_ref_id: self.next_id(),
1748            },
1749            span: opaque_ty_span,
1750        })
1751    }
1752
1753    #[instrument(level = "trace", skip(self))]
1754    fn lower_param_bound(
1755        &mut self,
1756        tpb: &GenericBound,
1757        itctx: ImplTraitContext,
1758    ) -> hir::GenericBound<'hir> {
1759        match tpb {
1760            GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1761            GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1762                lifetime,
1763                LifetimeSource::OutlivesBound,
1764                lifetime.ident.into(),
1765            )),
1766            GenericBound::Use(args, span) => hir::GenericBound::Use(
1767                self.lower_precise_capturing_args(args),
1768                self.lower_span(*span),
1769            ),
1770        }
1771    }
1772
1773    fn lower_lifetime(
1774        &mut self,
1775        l: &Lifetime,
1776        source: LifetimeSource,
1777        syntax: LifetimeSyntax,
1778    ) -> &'hir hir::Lifetime {
1779        self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1780    }
1781
1782    fn lower_lifetime_hidden_in_path(
1783        &mut self,
1784        id: NodeId,
1785        span: Span,
1786        angle_brackets: AngleBrackets,
1787    ) -> &'hir hir::Lifetime {
1788        self.new_named_lifetime(
1789            id,
1790            id,
1791            Ident::new(kw::UnderscoreLifetime, span),
1792            LifetimeSource::Path { angle_brackets },
1793            LifetimeSyntax::Implicit,
1794        )
1795    }
1796
1797    #[instrument(level = "debug", skip(self))]
1798    fn new_named_lifetime(
1799        &mut self,
1800        id: NodeId,
1801        new_id: NodeId,
1802        ident: Ident,
1803        source: LifetimeSource,
1804        syntax: LifetimeSyntax,
1805    ) -> &'hir hir::Lifetime {
1806        let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1807        let res = match res {
1808            LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1809            LifetimeRes::Fresh { param, .. } => {
1810                debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1811                let param = self.local_def_id(param);
1812                hir::LifetimeKind::Param(param)
1813            }
1814            LifetimeRes::Infer => {
1815                debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1816                hir::LifetimeKind::Infer
1817            }
1818            LifetimeRes::Static { .. } => {
1819                debug_assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1820                hir::LifetimeKind::Static
1821            }
1822            LifetimeRes::Error => hir::LifetimeKind::Error,
1823            LifetimeRes::ElidedAnchor { .. } => {
1824                panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1825            }
1826        };
1827
1828        debug!(?res);
1829        self.arena.alloc(hir::Lifetime::new(
1830            self.lower_node_id(new_id),
1831            self.lower_ident(ident),
1832            res,
1833            source,
1834            syntax,
1835        ))
1836    }
1837
1838    fn lower_generic_params_mut(
1839        &mut self,
1840        params: &[GenericParam],
1841        source: hir::GenericParamSource,
1842    ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1843        params.iter().map(move |param| self.lower_generic_param(param, source))
1844    }
1845
1846    fn lower_generic_params(
1847        &mut self,
1848        params: &[GenericParam],
1849        source: hir::GenericParamSource,
1850    ) -> &'hir [hir::GenericParam<'hir>] {
1851        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1852    }
1853
1854    #[instrument(level = "trace", skip(self))]
1855    fn lower_generic_param(
1856        &mut self,
1857        param: &GenericParam,
1858        source: hir::GenericParamSource,
1859    ) -> hir::GenericParam<'hir> {
1860        let (name, kind) = self.lower_generic_param_kind(param, source);
1861
1862        let hir_id = self.lower_node_id(param.id);
1863        self.lower_attrs(hir_id, &param.attrs, param.span());
1864        hir::GenericParam {
1865            hir_id,
1866            def_id: self.local_def_id(param.id),
1867            name,
1868            span: self.lower_span(param.span()),
1869            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
1870            kind,
1871            colon_span: param.colon_span.map(|s| self.lower_span(s)),
1872            source,
1873        }
1874    }
1875
1876    fn lower_generic_param_kind(
1877        &mut self,
1878        param: &GenericParam,
1879        source: hir::GenericParamSource,
1880    ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1881        match &param.kind {
1882            GenericParamKind::Lifetime => {
1883                // AST resolution emitted an error on those parameters, so we lower them using
1884                // `ParamName::Error`.
1885                let ident = self.lower_ident(param.ident);
1886                let param_name =
1887                    if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1888                        ParamName::Error(ident)
1889                    } else {
1890                        ParamName::Plain(ident)
1891                    };
1892                let kind =
1893                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1894
1895                (param_name, kind)
1896            }
1897            GenericParamKind::Type { default, .. } => {
1898                // Not only do we deny type param defaults in binders but we also map them to `None`
1899                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1900                let default = default
1901                    .as_ref()
1902                    .filter(|_| match source {
1903                        hir::GenericParamSource::Generics => true,
1904                        hir::GenericParamSource::Binder => {
1905                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1906                                span: param.span(),
1907                            });
1908
1909                            false
1910                        }
1911                    })
1912                    .map(|def| {
1913                        self.lower_ty(
1914                            def,
1915                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1916                        )
1917                    });
1918
1919                let kind = hir::GenericParamKind::Type { default, synthetic: false };
1920
1921                (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1922            }
1923            GenericParamKind::Const { ty, kw_span: _, default } => {
1924                let ty = self
1925                    .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1926
1927                // Not only do we deny const param defaults in binders but we also map them to `None`
1928                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1929                let default = default
1930                    .as_ref()
1931                    .filter(|_| match source {
1932                        hir::GenericParamSource::Generics => true,
1933                        hir::GenericParamSource::Binder => {
1934                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1935                                span: param.span(),
1936                            });
1937
1938                            false
1939                        }
1940                    })
1941                    .map(|def| self.lower_anon_const_to_const_arg(def));
1942
1943                (
1944                    hir::ParamName::Plain(self.lower_ident(param.ident)),
1945                    hir::GenericParamKind::Const { ty, default, synthetic: false },
1946                )
1947            }
1948        }
1949    }
1950
1951    fn lower_trait_ref(
1952        &mut self,
1953        modifiers: ast::TraitBoundModifiers,
1954        p: &TraitRef,
1955        itctx: ImplTraitContext,
1956    ) -> hir::TraitRef<'hir> {
1957        let path = match self.lower_qpath(
1958            p.ref_id,
1959            &None,
1960            &p.path,
1961            ParamMode::Explicit,
1962            AllowReturnTypeNotation::No,
1963            itctx,
1964            Some(modifiers),
1965        ) {
1966            hir::QPath::Resolved(None, path) => path,
1967            qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
1968        };
1969        hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1970    }
1971
1972    #[instrument(level = "debug", skip(self))]
1973    fn lower_poly_trait_ref(
1974        &mut self,
1975        p: &PolyTraitRef,
1976        itctx: ImplTraitContext,
1977    ) -> hir::PolyTraitRef<'hir> {
1978        let bound_generic_params =
1979            self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
1980        let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
1981        let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
1982        hir::PolyTraitRef {
1983            bound_generic_params,
1984            modifiers,
1985            trait_ref,
1986            span: self.lower_span(p.span),
1987        }
1988    }
1989
1990    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1991        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1992    }
1993
1994    #[instrument(level = "debug", skip(self), ret)]
1995    fn lower_param_bounds(
1996        &mut self,
1997        bounds: &[GenericBound],
1998        itctx: ImplTraitContext,
1999    ) -> hir::GenericBounds<'hir> {
2000        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2001    }
2002
2003    fn lower_param_bounds_mut(
2004        &mut self,
2005        bounds: &[GenericBound],
2006        itctx: ImplTraitContext,
2007    ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2008        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2009    }
2010
2011    #[instrument(level = "debug", skip(self), ret)]
2012    fn lower_universal_param_and_bounds(
2013        &mut self,
2014        node_id: NodeId,
2015        span: Span,
2016        ident: Ident,
2017        bounds: &[GenericBound],
2018    ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2019        // Add a definition for the in-band `Param`.
2020        let def_id = self.local_def_id(node_id);
2021        let span = self.lower_span(span);
2022
2023        // Set the name to `impl Bound1 + Bound2`.
2024        let param = hir::GenericParam {
2025            hir_id: self.lower_node_id(node_id),
2026            def_id,
2027            name: ParamName::Plain(self.lower_ident(ident)),
2028            pure_wrt_drop: false,
2029            span,
2030            kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2031            colon_span: None,
2032            source: hir::GenericParamSource::Generics,
2033        };
2034
2035        let preds = self.lower_generic_bound_predicate(
2036            ident,
2037            node_id,
2038            &GenericParamKind::Type { default: None },
2039            bounds,
2040            /* colon_span */ None,
2041            span,
2042            ImplTraitContext::Universal,
2043            hir::PredicateOrigin::ImplTrait,
2044        );
2045
2046        let hir_id = self.next_id();
2047        let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2048        let ty = hir::TyKind::Path(hir::QPath::Resolved(
2049            None,
2050            self.arena.alloc(hir::Path {
2051                span,
2052                res,
2053                segments:
2054                    arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2055            }),
2056        ));
2057
2058        (param, preds, ty)
2059    }
2060
2061    /// Lowers a block directly to an expression, presuming that it
2062    /// has no attributes and is not targeted by a `break`.
2063    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2064        let block = self.lower_block(b, false);
2065        self.expr_block(block)
2066    }
2067
2068    fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2069        // We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
2070        // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
2071        match c.value.peel_parens().kind {
2072            ExprKind::Underscore => {
2073                if !self.tcx.features().generic_arg_infer() {
2074                    feature_err(
2075                        &self.tcx.sess,
2076                        sym::generic_arg_infer,
2077                        c.value.span,
2078                        fluent_generated::ast_lowering_underscore_array_length_unstable,
2079                    )
2080                    .stash(c.value.span, StashKey::UnderscoreForArrayLengths);
2081                }
2082                let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2083                self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2084            }
2085            _ => self.lower_anon_const_to_const_arg(c),
2086        }
2087    }
2088
2089    /// Used when lowering a type argument that turned out to actually be a const argument.
2090    ///
2091    /// Only use for that purpose since otherwise it will create a duplicate def.
2092    #[instrument(level = "debug", skip(self))]
2093    fn lower_const_path_to_const_arg(
2094        &mut self,
2095        path: &Path,
2096        res: Res<NodeId>,
2097        ty_id: NodeId,
2098        span: Span,
2099    ) -> &'hir hir::ConstArg<'hir> {
2100        let tcx = self.tcx;
2101
2102        let ct_kind = if path
2103            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2104            && (tcx.features().min_generic_const_args()
2105                || matches!(res, Res::Def(DefKind::ConstParam, _)))
2106        {
2107            let qpath = self.lower_qpath(
2108                ty_id,
2109                &None,
2110                path,
2111                ParamMode::Optional,
2112                AllowReturnTypeNotation::No,
2113                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2114                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2115                None,
2116            );
2117            hir::ConstArgKind::Path(qpath)
2118        } else {
2119            // Construct an AnonConst where the expr is the "ty"'s path.
2120            let node_id = self.next_node_id();
2121            let span = self.lower_span(span);
2122
2123            // Add a definition for the in-band const def.
2124            // We're lowering a const argument that was originally thought to be a type argument,
2125            // so the def collector didn't create the def ahead of time. That's why we have to do
2126            // it here.
2127            let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2128            let hir_id = self.lower_node_id(node_id);
2129
2130            let path_expr = Expr {
2131                id: ty_id,
2132                kind: ExprKind::Path(None, path.clone()),
2133                span,
2134                attrs: AttrVec::new(),
2135                tokens: None,
2136            };
2137
2138            let ct = self.with_new_scopes(span, |this| {
2139                self.arena.alloc(hir::AnonConst {
2140                    def_id,
2141                    hir_id,
2142                    body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2143                    span,
2144                })
2145            });
2146            hir::ConstArgKind::Anon(ct)
2147        };
2148
2149        self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2150    }
2151
2152    /// See [`hir::ConstArg`] for when to use this function vs
2153    /// [`Self::lower_anon_const_to_anon_const`].
2154    fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2155        self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2156    }
2157
2158    #[instrument(level = "debug", skip(self))]
2159    fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2160        let tcx = self.tcx;
2161        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
2162        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
2163        let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2164            && let [stmt] = block.stmts.as_slice()
2165            && let StmtKind::Expr(expr) = &stmt.kind
2166            && let ExprKind::Path(..) = &expr.kind
2167        {
2168            expr
2169        } else {
2170            &anon.value
2171        };
2172        let maybe_res =
2173            self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2174        if let ExprKind::Path(qself, path) = &expr.kind
2175            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2176            && (tcx.features().min_generic_const_args()
2177                || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2178        {
2179            let qpath = self.lower_qpath(
2180                expr.id,
2181                qself,
2182                path,
2183                ParamMode::Optional,
2184                AllowReturnTypeNotation::No,
2185                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2186                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2187                None,
2188            );
2189
2190            return ConstArg {
2191                hir_id: self.lower_node_id(anon.id),
2192                kind: hir::ConstArgKind::Path(qpath),
2193            };
2194        }
2195
2196        let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2197        ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2198    }
2199
2200    /// See [`hir::ConstArg`] for when to use this function vs
2201    /// [`Self::lower_anon_const_to_const_arg`].
2202    fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2203        self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2204            let def_id = this.local_def_id(c.id);
2205            let hir_id = this.lower_node_id(c.id);
2206            hir::AnonConst {
2207                def_id,
2208                hir_id,
2209                body: this.lower_const_body(c.value.span, Some(&c.value)),
2210                span: this.lower_span(c.value.span),
2211            }
2212        }))
2213    }
2214
2215    fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2216        match u {
2217            CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2218            UserProvided => hir::UnsafeSource::UserProvided,
2219        }
2220    }
2221
2222    fn lower_trait_bound_modifiers(
2223        &mut self,
2224        modifiers: TraitBoundModifiers,
2225    ) -> hir::TraitBoundModifiers {
2226        hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2227    }
2228
2229    // Helper methods for building HIR.
2230
2231    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2232        hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2233    }
2234
2235    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2236        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2237    }
2238
2239    fn stmt_let_pat(
2240        &mut self,
2241        attrs: Option<&'hir [hir::Attribute]>,
2242        span: Span,
2243        init: Option<&'hir hir::Expr<'hir>>,
2244        pat: &'hir hir::Pat<'hir>,
2245        source: hir::LocalSource,
2246    ) -> hir::Stmt<'hir> {
2247        let hir_id = self.next_id();
2248        if let Some(a) = attrs {
2249            debug_assert!(!a.is_empty());
2250            self.attrs.insert(hir_id.local_id, a);
2251        }
2252        let local = hir::LetStmt {
2253            super_: None,
2254            hir_id,
2255            init,
2256            pat,
2257            els: None,
2258            source,
2259            span: self.lower_span(span),
2260            ty: None,
2261        };
2262        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2263    }
2264
2265    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2266        self.block_all(expr.span, &[], Some(expr))
2267    }
2268
2269    fn block_all(
2270        &mut self,
2271        span: Span,
2272        stmts: &'hir [hir::Stmt<'hir>],
2273        expr: Option<&'hir hir::Expr<'hir>>,
2274    ) -> &'hir hir::Block<'hir> {
2275        let blk = hir::Block {
2276            stmts,
2277            expr,
2278            hir_id: self.next_id(),
2279            rules: hir::BlockCheckMode::DefaultBlock,
2280            span: self.lower_span(span),
2281            targeted_by_break: false,
2282        };
2283        self.arena.alloc(blk)
2284    }
2285
2286    fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2287        let field = self.single_pat_field(span, pat);
2288        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2289    }
2290
2291    fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2292        let field = self.single_pat_field(span, pat);
2293        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2294    }
2295
2296    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2297        let field = self.single_pat_field(span, pat);
2298        self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2299    }
2300
2301    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2302        self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2303    }
2304
2305    fn single_pat_field(
2306        &mut self,
2307        span: Span,
2308        pat: &'hir hir::Pat<'hir>,
2309    ) -> &'hir [hir::PatField<'hir>] {
2310        let field = hir::PatField {
2311            hir_id: self.next_id(),
2312            ident: Ident::new(sym::integer(0), self.lower_span(span)),
2313            is_shorthand: false,
2314            pat,
2315            span: self.lower_span(span),
2316        };
2317        arena_vec![self; field]
2318    }
2319
2320    fn pat_lang_item_variant(
2321        &mut self,
2322        span: Span,
2323        lang_item: hir::LangItem,
2324        fields: &'hir [hir::PatField<'hir>],
2325    ) -> &'hir hir::Pat<'hir> {
2326        let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2327        self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2328    }
2329
2330    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2331        self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2332    }
2333
2334    fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2335        self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2336    }
2337
2338    fn pat_ident_binding_mode(
2339        &mut self,
2340        span: Span,
2341        ident: Ident,
2342        bm: hir::BindingMode,
2343    ) -> (&'hir hir::Pat<'hir>, HirId) {
2344        let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2345        (self.arena.alloc(pat), hir_id)
2346    }
2347
2348    fn pat_ident_binding_mode_mut(
2349        &mut self,
2350        span: Span,
2351        ident: Ident,
2352        bm: hir::BindingMode,
2353    ) -> (hir::Pat<'hir>, HirId) {
2354        let hir_id = self.next_id();
2355
2356        (
2357            hir::Pat {
2358                hir_id,
2359                kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2360                span: self.lower_span(span),
2361                default_binding_modes: true,
2362            },
2363            hir_id,
2364        )
2365    }
2366
2367    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2368        self.arena.alloc(hir::Pat {
2369            hir_id: self.next_id(),
2370            kind,
2371            span: self.lower_span(span),
2372            default_binding_modes: true,
2373        })
2374    }
2375
2376    fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2377        hir::Pat {
2378            hir_id: self.next_id(),
2379            kind,
2380            span: self.lower_span(span),
2381            default_binding_modes: false,
2382        }
2383    }
2384
2385    fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2386        let kind = match qpath {
2387            hir::QPath::Resolved(None, path) => {
2388                // Turn trait object paths into `TyKind::TraitObject` instead.
2389                match path.res {
2390                    Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2391                        let principal = hir::PolyTraitRef {
2392                            bound_generic_params: &[],
2393                            modifiers: hir::TraitBoundModifiers::NONE,
2394                            trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2395                            span: self.lower_span(span),
2396                        };
2397
2398                        // The original ID is taken by the `PolyTraitRef`,
2399                        // so the `Ty` itself needs a different one.
2400                        hir_id = self.next_id();
2401                        hir::TyKind::TraitObject(
2402                            arena_vec![self; principal],
2403                            TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2404                        )
2405                    }
2406                    _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2407                }
2408            }
2409            _ => hir::TyKind::Path(qpath),
2410        };
2411
2412        hir::Ty { hir_id, kind, span: self.lower_span(span) }
2413    }
2414
2415    /// Invoked to create the lifetime argument(s) for an elided trait object
2416    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2417    /// when the bound is written, even if it is written with `'_` like in
2418    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2419    fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2420        let r = hir::Lifetime::new(
2421            self.next_id(),
2422            Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2423            hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2424            LifetimeSource::Other,
2425            LifetimeSyntax::Implicit,
2426        );
2427        debug!("elided_dyn_bound: r={:?}", r);
2428        self.arena.alloc(r)
2429    }
2430}
2431
2432/// Helper struct for the delayed construction of [`hir::GenericArgs`].
2433struct GenericArgsCtor<'hir> {
2434    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2435    constraints: &'hir [hir::AssocItemConstraint<'hir>],
2436    parenthesized: hir::GenericArgsParentheses,
2437    span: Span,
2438}
2439
2440impl<'hir> GenericArgsCtor<'hir> {
2441    fn is_empty(&self) -> bool {
2442        self.args.is_empty()
2443            && self.constraints.is_empty()
2444            && self.parenthesized == hir::GenericArgsParentheses::No
2445    }
2446
2447    fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2448        let ga = hir::GenericArgs {
2449            args: this.arena.alloc_from_iter(self.args),
2450            constraints: self.constraints,
2451            parenthesized: self.parenthesized,
2452            span_ext: this.lower_span(self.span),
2453        };
2454        this.arena.alloc(ga)
2455    }
2456}