rustc_ast_lowering/
lib.rs

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