rustc_ast_lowering/
lib.rs

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