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                        parens: ast::Parens::No,
1213                    },
1214                    itctx,
1215                );
1216                let bounds = this.arena.alloc_from_iter([bound]);
1217                let lifetime_bound = this.elided_dyn_bound(t.span);
1218                (bounds, lifetime_bound)
1219            });
1220            let kind = hir::TyKind::TraitObject(
1221                bounds,
1222                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1223            );
1224            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1225        }
1226
1227        let id = self.lower_node_id(t.id);
1228        let qpath = self.lower_qpath(
1229            t.id,
1230            qself,
1231            path,
1232            param_mode,
1233            AllowReturnTypeNotation::Yes,
1234            itctx,
1235            None,
1236        );
1237        self.ty_path(id, t.span, qpath)
1238    }
1239
1240    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1241        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1242    }
1243
1244    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1245        self.ty(span, hir::TyKind::Tup(tys))
1246    }
1247
1248    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1249        let kind = match &t.kind {
1250            TyKind::Infer => hir::TyKind::Infer(()),
1251            TyKind::Err(guar) => hir::TyKind::Err(*guar),
1252            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1253            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1254            TyKind::Ref(region, mt) => {
1255                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1256                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1257            }
1258            TyKind::PinnedRef(region, mt) => {
1259                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1260                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1261                let span = self.lower_span(t.span);
1262                let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1263                let args = self.arena.alloc(hir::GenericArgs {
1264                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1265                    constraints: &[],
1266                    parenthesized: hir::GenericArgsParentheses::No,
1267                    span_ext: span,
1268                });
1269                let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
1270                hir::TyKind::Path(path)
1271            }
1272            TyKind::FnPtr(f) => {
1273                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1274                hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {
1275                    generic_params,
1276                    safety: self.lower_safety(f.safety, hir::Safety::Safe),
1277                    abi: self.lower_extern(f.ext),
1278                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1279                    param_idents: self.lower_fn_params_to_idents(&f.decl),
1280                }))
1281            }
1282            TyKind::UnsafeBinder(f) => {
1283                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1284                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1285                    generic_params,
1286                    inner_ty: self.lower_ty(&f.inner_ty, itctx),
1287                }))
1288            }
1289            TyKind::Never => hir::TyKind::Never,
1290            TyKind::Tup(tys) => hir::TyKind::Tup(
1291                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1292            ),
1293            TyKind::Paren(ty) => {
1294                return self.lower_ty_direct(ty, itctx);
1295            }
1296            TyKind::Path(qself, path) => {
1297                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1298            }
1299            TyKind::ImplicitSelf => {
1300                let hir_id = self.next_id();
1301                let res = self.expect_full_res(t.id);
1302                let res = self.lower_res(res);
1303                hir::TyKind::Path(hir::QPath::Resolved(
1304                    None,
1305                    self.arena.alloc(hir::Path {
1306                        res,
1307                        segments: arena_vec![self; hir::PathSegment::new(
1308                            Ident::with_dummy_span(kw::SelfUpper),
1309                            hir_id,
1310                            res
1311                        )],
1312                        span: self.lower_span(t.span),
1313                    }),
1314                ))
1315            }
1316            TyKind::Array(ty, length) => hir::TyKind::Array(
1317                self.lower_ty(ty, itctx),
1318                self.lower_array_length_to_const_arg(length),
1319            ),
1320            TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1321            TyKind::TraitObject(bounds, kind) => {
1322                let mut lifetime_bound = None;
1323                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1324                    let bounds =
1325                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1326                            // We can safely ignore constness here since AST validation
1327                            // takes care of rejecting invalid modifier combinations and
1328                            // const trait bounds in trait object types.
1329                            GenericBound::Trait(ty) => {
1330                                let trait_ref = this.lower_poly_trait_ref(ty, itctx);
1331                                Some(trait_ref)
1332                            }
1333                            GenericBound::Outlives(lifetime) => {
1334                                if lifetime_bound.is_none() {
1335                                    lifetime_bound = Some(this.lower_lifetime(
1336                                        lifetime,
1337                                        LifetimeSource::Other,
1338                                        lifetime.ident.into(),
1339                                    ));
1340                                }
1341                                None
1342                            }
1343                            // Ignore `use` syntax since that is not valid in objects.
1344                            GenericBound::Use(_, span) => {
1345                                this.dcx()
1346                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");
1347                                None
1348                            }
1349                        }));
1350                    let lifetime_bound =
1351                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1352                    (bounds, lifetime_bound)
1353                });
1354                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1355            }
1356            TyKind::ImplTrait(def_node_id, bounds) => {
1357                let span = t.span;
1358                match itctx {
1359                    ImplTraitContext::OpaqueTy { origin } => {
1360                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1361                    }
1362                    ImplTraitContext::Universal => {
1363                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1364                            ast::GenericBound::Use(_, span) => Some(span),
1365                            _ => None,
1366                        }) {
1367                            self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1368                        }
1369
1370                        let def_id = self.local_def_id(*def_node_id);
1371                        let name = self.tcx.item_name(def_id.to_def_id());
1372                        let ident = Ident::new(name, span);
1373                        let (param, bounds, path) = self.lower_universal_param_and_bounds(
1374                            *def_node_id,
1375                            span,
1376                            ident,
1377                            bounds,
1378                        );
1379                        self.impl_trait_defs.push(param);
1380                        if let Some(bounds) = bounds {
1381                            self.impl_trait_bounds.push(bounds);
1382                        }
1383                        path
1384                    }
1385                    ImplTraitContext::InBinding => {
1386                        hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
1387                    }
1388                    ImplTraitContext::FeatureGated(position, feature) => {
1389                        let guar = self
1390                            .tcx
1391                            .sess
1392                            .create_feature_err(
1393                                MisplacedImplTrait {
1394                                    span: t.span,
1395                                    position: DiagArgFromDisplay(&position),
1396                                },
1397                                feature,
1398                            )
1399                            .emit();
1400                        hir::TyKind::Err(guar)
1401                    }
1402                    ImplTraitContext::Disallowed(position) => {
1403                        let guar = self.dcx().emit_err(MisplacedImplTrait {
1404                            span: t.span,
1405                            position: DiagArgFromDisplay(&position),
1406                        });
1407                        hir::TyKind::Err(guar)
1408                    }
1409                }
1410            }
1411            TyKind::Pat(ty, pat) => {
1412                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1413            }
1414            TyKind::MacCall(_) => {
1415                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1416            }
1417            TyKind::CVarArgs => {
1418                let guar = self.dcx().span_delayed_bug(
1419                    t.span,
1420                    "`TyKind::CVarArgs` should have been handled elsewhere",
1421                );
1422                hir::TyKind::Err(guar)
1423            }
1424            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1425        };
1426
1427        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1428    }
1429
1430    fn lower_ty_direct_lifetime(
1431        &mut self,
1432        t: &Ty,
1433        region: Option<Lifetime>,
1434    ) -> &'hir hir::Lifetime {
1435        let (region, syntax) = match region {
1436            Some(region) => (region, region.ident.into()),
1437
1438            None => {
1439                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1440                    self.resolver.get_lifetime_res(t.id)
1441                {
1442                    assert_eq!(start.plus(1), end);
1443                    start
1444                } else {
1445                    self.next_node_id()
1446                };
1447                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1448                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1449                (region, LifetimeSyntax::Implicit)
1450            }
1451        };
1452        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
1453    }
1454
1455    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1456    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1457    /// HIR type that references the TAIT.
1458    ///
1459    /// Given a function definition like:
1460    ///
1461    /// ```rust
1462    /// use std::fmt::Debug;
1463    ///
1464    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1465    ///     x
1466    /// }
1467    /// ```
1468    ///
1469    /// we will create a TAIT definition in the HIR like
1470    ///
1471    /// ```rust,ignore (pseudo-Rust)
1472    /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1473    /// ```
1474    ///
1475    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1476    ///
1477    /// ```rust,ignore (pseudo-Rust)
1478    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1479    /// ```
1480    ///
1481    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1482    /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1483    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1484    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1485    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1486    #[instrument(level = "debug", skip(self), ret)]
1487    fn lower_opaque_impl_trait(
1488        &mut self,
1489        span: Span,
1490        origin: hir::OpaqueTyOrigin<LocalDefId>,
1491        opaque_ty_node_id: NodeId,
1492        bounds: &GenericBounds,
1493        itctx: ImplTraitContext,
1494    ) -> hir::TyKind<'hir> {
1495        // Make sure we know that some funky desugaring has been going on here.
1496        // This is a first: there is code in other places like for loop
1497        // desugaring that explicitly states that we don't want to track that.
1498        // Not tracking it makes lints in rustc and clippy very fragile, as
1499        // frequently opened issues show.
1500        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1501
1502        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1503            this.lower_param_bounds(bounds, itctx)
1504        })
1505    }
1506
1507    fn lower_opaque_inner(
1508        &mut self,
1509        opaque_ty_node_id: NodeId,
1510        origin: hir::OpaqueTyOrigin<LocalDefId>,
1511        opaque_ty_span: Span,
1512        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1513    ) -> hir::TyKind<'hir> {
1514        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1515        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1516        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1517
1518        let bounds = lower_item_bounds(self);
1519        let opaque_ty_def = hir::OpaqueTy {
1520            hir_id: opaque_ty_hir_id,
1521            def_id: opaque_ty_def_id,
1522            bounds,
1523            origin,
1524            span: self.lower_span(opaque_ty_span),
1525        };
1526        let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1527
1528        hir::TyKind::OpaqueDef(opaque_ty_def)
1529    }
1530
1531    fn lower_precise_capturing_args(
1532        &mut self,
1533        precise_capturing_args: &[PreciseCapturingArg],
1534    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1535        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1536            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1537                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1538            ),
1539            PreciseCapturingArg::Arg(path, id) => {
1540                let [segment] = path.segments.as_slice() else {
1541                    panic!();
1542                };
1543                let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1544                    partial_res.full_res().expect("no partial res expected for precise capture arg")
1545                });
1546                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1547                    hir_id: self.lower_node_id(*id),
1548                    ident: self.lower_ident(segment.ident),
1549                    res: self.lower_res(res),
1550                })
1551            }
1552        }))
1553    }
1554
1555    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1556        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1557            PatKind::Missing => None,
1558            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1559            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1560            _ => {
1561                self.dcx().span_delayed_bug(
1562                    param.pat.span,
1563                    "non-missing/ident/wild param pat must trigger an error",
1564                );
1565                None
1566            }
1567        }))
1568    }
1569
1570    /// Lowers a function declaration.
1571    ///
1572    /// `decl`: the unlowered (AST) function declaration.
1573    ///
1574    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given
1575    /// `NodeId`.
1576    ///
1577    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is
1578    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.
1579    #[instrument(level = "debug", skip(self))]
1580    fn lower_fn_decl(
1581        &mut self,
1582        decl: &FnDecl,
1583        fn_node_id: NodeId,
1584        fn_span: Span,
1585        kind: FnDeclKind,
1586        coro: Option<CoroutineKind>,
1587    ) -> &'hir hir::FnDecl<'hir> {
1588        let c_variadic = decl.c_variadic();
1589
1590        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1591        // as they are not explicit in HIR/Ty function signatures.
1592        // (instead, the `c_variadic` flag is set to `true`)
1593        let mut inputs = &decl.inputs[..];
1594        if c_variadic {
1595            inputs = &inputs[..inputs.len() - 1];
1596        }
1597        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1598            let itctx = match kind {
1599                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1600                    ImplTraitContext::Universal
1601                }
1602                FnDeclKind::ExternFn => {
1603                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1604                }
1605                FnDeclKind::Closure => {
1606                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1607                }
1608                FnDeclKind::Pointer => {
1609                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1610                }
1611            };
1612            self.lower_ty_direct(&param.ty, itctx)
1613        }));
1614
1615        let output = match coro {
1616            Some(coro) => {
1617                let fn_def_id = self.local_def_id(fn_node_id);
1618                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1619            }
1620            None => match &decl.output {
1621                FnRetTy::Ty(ty) => {
1622                    let itctx = match kind {
1623                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1624                            origin: hir::OpaqueTyOrigin::FnReturn {
1625                                parent: self.local_def_id(fn_node_id),
1626                                in_trait_or_impl: None,
1627                            },
1628                        },
1629                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1630                            origin: hir::OpaqueTyOrigin::FnReturn {
1631                                parent: self.local_def_id(fn_node_id),
1632                                in_trait_or_impl: Some(hir::RpitContext::Trait),
1633                            },
1634                        },
1635                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1636                            origin: hir::OpaqueTyOrigin::FnReturn {
1637                                parent: self.local_def_id(fn_node_id),
1638                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1639                            },
1640                        },
1641                        FnDeclKind::ExternFn => {
1642                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1643                        }
1644                        FnDeclKind::Closure => {
1645                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1646                        }
1647                        FnDeclKind::Pointer => {
1648                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1649                        }
1650                    };
1651                    hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1652                }
1653                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1654            },
1655        };
1656
1657        self.arena.alloc(hir::FnDecl {
1658            inputs,
1659            output,
1660            c_variadic,
1661            lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1662            implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1663                let is_mutable_pat = matches!(
1664                    arg.pat.kind,
1665                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1666                );
1667
1668                match &arg.ty.kind {
1669                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1670                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1671                    // Given we are only considering `ImplicitSelf` types, we needn't consider
1672                    // the case where we have a mutable pattern to a reference as that would
1673                    // no longer be an `ImplicitSelf`.
1674                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1675                        if mt.ty.kind.is_implicit_self() =>
1676                    {
1677                        match mt.mutbl {
1678                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1679                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1680                        }
1681                    }
1682                    _ => hir::ImplicitSelfKind::None,
1683                }
1684            }),
1685        })
1686    }
1687
1688    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1689    // combined with the following definition of `OpaqueTy`:
1690    //
1691    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1692    //
1693    // `output`: unlowered output type (`T` in `-> T`)
1694    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)
1695    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1696    #[instrument(level = "debug", skip(self))]
1697    fn lower_coroutine_fn_ret_ty(
1698        &mut self,
1699        output: &FnRetTy,
1700        fn_def_id: LocalDefId,
1701        coro: CoroutineKind,
1702        fn_kind: FnDeclKind,
1703        fn_span: Span,
1704    ) -> hir::FnRetTy<'hir> {
1705        let span = self.lower_span(fn_span);
1706
1707        let (opaque_ty_node_id, allowed_features) = match coro {
1708            CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1709            CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1710            CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1711                (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1712            }
1713        };
1714
1715        let opaque_ty_span =
1716            self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1717
1718        let in_trait_or_impl = match fn_kind {
1719            FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1720            FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1721            FnDeclKind::Fn | FnDeclKind::Inherent => None,
1722            FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1723        };
1724
1725        let opaque_ty_ref = self.lower_opaque_inner(
1726            opaque_ty_node_id,
1727            hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1728            opaque_ty_span,
1729            |this| {
1730                let bound = this.lower_coroutine_fn_output_type_to_bound(
1731                    output,
1732                    coro,
1733                    opaque_ty_span,
1734                    ImplTraitContext::OpaqueTy {
1735                        origin: hir::OpaqueTyOrigin::FnReturn {
1736                            parent: fn_def_id,
1737                            in_trait_or_impl,
1738                        },
1739                    },
1740                );
1741                arena_vec![this; bound]
1742            },
1743        );
1744
1745        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1746        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1747    }
1748
1749    /// Transforms `-> T` into `Future<Output = T>`.
1750    fn lower_coroutine_fn_output_type_to_bound(
1751        &mut self,
1752        output: &FnRetTy,
1753        coro: CoroutineKind,
1754        opaque_ty_span: Span,
1755        itctx: ImplTraitContext,
1756    ) -> hir::GenericBound<'hir> {
1757        // Compute the `T` in `Future<Output = T>` from the return type.
1758        let output_ty = match output {
1759            FnRetTy::Ty(ty) => {
1760                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1761                // `impl Future` opaque type that `async fn` implicitly
1762                // generates.
1763                self.lower_ty(ty, itctx)
1764            }
1765            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1766        };
1767
1768        // "<$assoc_ty_name = T>"
1769        let (assoc_ty_name, trait_lang_item) = match coro {
1770            CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1771            CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1772            CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1773        };
1774
1775        let bound_args = self.arena.alloc(hir::GenericArgs {
1776            args: &[],
1777            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1778            parenthesized: hir::GenericArgsParentheses::No,
1779            span_ext: DUMMY_SP,
1780        });
1781
1782        hir::GenericBound::Trait(hir::PolyTraitRef {
1783            bound_generic_params: &[],
1784            modifiers: hir::TraitBoundModifiers::NONE,
1785            trait_ref: hir::TraitRef {
1786                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1787                hir_ref_id: self.next_id(),
1788            },
1789            span: opaque_ty_span,
1790        })
1791    }
1792
1793    #[instrument(level = "trace", skip(self))]
1794    fn lower_param_bound(
1795        &mut self,
1796        tpb: &GenericBound,
1797        itctx: ImplTraitContext,
1798    ) -> hir::GenericBound<'hir> {
1799        match tpb {
1800            GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
1801            GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1802                lifetime,
1803                LifetimeSource::OutlivesBound,
1804                lifetime.ident.into(),
1805            )),
1806            GenericBound::Use(args, span) => hir::GenericBound::Use(
1807                self.lower_precise_capturing_args(args),
1808                self.lower_span(*span),
1809            ),
1810        }
1811    }
1812
1813    fn lower_lifetime(
1814        &mut self,
1815        l: &Lifetime,
1816        source: LifetimeSource,
1817        syntax: LifetimeSyntax,
1818    ) -> &'hir hir::Lifetime {
1819        self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1820    }
1821
1822    fn lower_lifetime_hidden_in_path(
1823        &mut self,
1824        id: NodeId,
1825        span: Span,
1826        angle_brackets: AngleBrackets,
1827    ) -> &'hir hir::Lifetime {
1828        self.new_named_lifetime(
1829            id,
1830            id,
1831            Ident::new(kw::UnderscoreLifetime, span),
1832            LifetimeSource::Path { angle_brackets },
1833            LifetimeSyntax::Implicit,
1834        )
1835    }
1836
1837    #[instrument(level = "debug", skip(self))]
1838    fn new_named_lifetime(
1839        &mut self,
1840        id: NodeId,
1841        new_id: NodeId,
1842        ident: Ident,
1843        source: LifetimeSource,
1844        syntax: LifetimeSyntax,
1845    ) -> &'hir hir::Lifetime {
1846        let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1847        let res = match res {
1848            LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1849            LifetimeRes::Fresh { param, .. } => {
1850                assert_eq!(ident.name, kw::UnderscoreLifetime);
1851                let param = self.local_def_id(param);
1852                hir::LifetimeKind::Param(param)
1853            }
1854            LifetimeRes::Infer => {
1855                assert_eq!(ident.name, kw::UnderscoreLifetime);
1856                hir::LifetimeKind::Infer
1857            }
1858            LifetimeRes::Static { .. } => {
1859                assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1860                hir::LifetimeKind::Static
1861            }
1862            LifetimeRes::Error => hir::LifetimeKind::Error,
1863            LifetimeRes::ElidedAnchor { .. } => {
1864                panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1865            }
1866        };
1867
1868        debug!(?res);
1869        self.arena.alloc(hir::Lifetime::new(
1870            self.lower_node_id(new_id),
1871            self.lower_ident(ident),
1872            res,
1873            source,
1874            syntax,
1875        ))
1876    }
1877
1878    fn lower_generic_params_mut(
1879        &mut self,
1880        params: &[GenericParam],
1881        source: hir::GenericParamSource,
1882    ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1883        params.iter().map(move |param| self.lower_generic_param(param, source))
1884    }
1885
1886    fn lower_generic_params(
1887        &mut self,
1888        params: &[GenericParam],
1889        source: hir::GenericParamSource,
1890    ) -> &'hir [hir::GenericParam<'hir>] {
1891        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1892    }
1893
1894    #[instrument(level = "trace", skip(self))]
1895    fn lower_generic_param(
1896        &mut self,
1897        param: &GenericParam,
1898        source: hir::GenericParamSource,
1899    ) -> hir::GenericParam<'hir> {
1900        let (name, kind) = self.lower_generic_param_kind(param, source);
1901
1902        let hir_id = self.lower_node_id(param.id);
1903        self.lower_attrs(hir_id, &param.attrs, param.span());
1904        hir::GenericParam {
1905            hir_id,
1906            def_id: self.local_def_id(param.id),
1907            name,
1908            span: self.lower_span(param.span()),
1909            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
1910            kind,
1911            colon_span: param.colon_span.map(|s| self.lower_span(s)),
1912            source,
1913        }
1914    }
1915
1916    fn lower_generic_param_kind(
1917        &mut self,
1918        param: &GenericParam,
1919        source: hir::GenericParamSource,
1920    ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1921        match &param.kind {
1922            GenericParamKind::Lifetime => {
1923                // AST resolution emitted an error on those parameters, so we lower them using
1924                // `ParamName::Error`.
1925                let ident = self.lower_ident(param.ident);
1926                let param_name =
1927                    if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1928                        ParamName::Error(ident)
1929                    } else {
1930                        ParamName::Plain(ident)
1931                    };
1932                let kind =
1933                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1934
1935                (param_name, kind)
1936            }
1937            GenericParamKind::Type { default, .. } => {
1938                // Not only do we deny type param defaults in binders but we also map them to `None`
1939                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1940                let default = default
1941                    .as_ref()
1942                    .filter(|_| match source {
1943                        hir::GenericParamSource::Generics => true,
1944                        hir::GenericParamSource::Binder => {
1945                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1946                                span: param.span(),
1947                            });
1948
1949                            false
1950                        }
1951                    })
1952                    .map(|def| {
1953                        self.lower_ty(
1954                            def,
1955                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1956                        )
1957                    });
1958
1959                let kind = hir::GenericParamKind::Type { default, synthetic: false };
1960
1961                (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1962            }
1963            GenericParamKind::Const { ty, span: _, default } => {
1964                let ty = self
1965                    .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1966
1967                // Not only do we deny const param defaults in binders but we also map them to `None`
1968                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1969                let default = default
1970                    .as_ref()
1971                    .filter(|_| match source {
1972                        hir::GenericParamSource::Generics => true,
1973                        hir::GenericParamSource::Binder => {
1974                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1975                                span: param.span(),
1976                            });
1977
1978                            false
1979                        }
1980                    })
1981                    .map(|def| self.lower_anon_const_to_const_arg(def));
1982
1983                (
1984                    hir::ParamName::Plain(self.lower_ident(param.ident)),
1985                    hir::GenericParamKind::Const { ty, default, synthetic: false },
1986                )
1987            }
1988        }
1989    }
1990
1991    fn lower_trait_ref(
1992        &mut self,
1993        modifiers: ast::TraitBoundModifiers,
1994        p: &TraitRef,
1995        itctx: ImplTraitContext,
1996    ) -> hir::TraitRef<'hir> {
1997        let path = match self.lower_qpath(
1998            p.ref_id,
1999            &None,
2000            &p.path,
2001            ParamMode::Explicit,
2002            AllowReturnTypeNotation::No,
2003            itctx,
2004            Some(modifiers),
2005        ) {
2006            hir::QPath::Resolved(None, path) => path,
2007            qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2008        };
2009        hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2010    }
2011
2012    #[instrument(level = "debug", skip(self))]
2013    fn lower_poly_trait_ref(
2014        &mut self,
2015        p: &PolyTraitRef,
2016        itctx: ImplTraitContext,
2017    ) -> hir::PolyTraitRef<'hir> {
2018        let bound_generic_params =
2019            self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
2020        let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
2021        let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
2022        hir::PolyTraitRef {
2023            bound_generic_params,
2024            modifiers,
2025            trait_ref,
2026            span: self.lower_span(p.span),
2027        }
2028    }
2029
2030    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2031        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2032    }
2033
2034    #[instrument(level = "debug", skip(self), ret)]
2035    fn lower_param_bounds(
2036        &mut self,
2037        bounds: &[GenericBound],
2038        itctx: ImplTraitContext,
2039    ) -> hir::GenericBounds<'hir> {
2040        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2041    }
2042
2043    fn lower_param_bounds_mut(
2044        &mut self,
2045        bounds: &[GenericBound],
2046        itctx: ImplTraitContext,
2047    ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2048        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2049    }
2050
2051    #[instrument(level = "debug", skip(self), ret)]
2052    fn lower_universal_param_and_bounds(
2053        &mut self,
2054        node_id: NodeId,
2055        span: Span,
2056        ident: Ident,
2057        bounds: &[GenericBound],
2058    ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2059        // Add a definition for the in-band `Param`.
2060        let def_id = self.local_def_id(node_id);
2061        let span = self.lower_span(span);
2062
2063        // Set the name to `impl Bound1 + Bound2`.
2064        let param = hir::GenericParam {
2065            hir_id: self.lower_node_id(node_id),
2066            def_id,
2067            name: ParamName::Plain(self.lower_ident(ident)),
2068            pure_wrt_drop: false,
2069            span,
2070            kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2071            colon_span: None,
2072            source: hir::GenericParamSource::Generics,
2073        };
2074
2075        let preds = self.lower_generic_bound_predicate(
2076            ident,
2077            node_id,
2078            &GenericParamKind::Type { default: None },
2079            bounds,
2080            /* colon_span */ None,
2081            span,
2082            ImplTraitContext::Universal,
2083            hir::PredicateOrigin::ImplTrait,
2084        );
2085
2086        let hir_id = self.next_id();
2087        let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2088        let ty = hir::TyKind::Path(hir::QPath::Resolved(
2089            None,
2090            self.arena.alloc(hir::Path {
2091                span,
2092                res,
2093                segments:
2094                    arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2095            }),
2096        ));
2097
2098        (param, preds, ty)
2099    }
2100
2101    /// Lowers a block directly to an expression, presuming that it
2102    /// has no attributes and is not targeted by a `break`.
2103    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2104        let block = self.lower_block(b, false);
2105        self.expr_block(block)
2106    }
2107
2108    fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2109        // We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
2110        // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
2111        match c.value.peel_parens().kind {
2112            ExprKind::Underscore => {
2113                let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2114                self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2115            }
2116            _ => self.lower_anon_const_to_const_arg(c),
2117        }
2118    }
2119
2120    /// Used when lowering a type argument that turned out to actually be a const argument.
2121    ///
2122    /// Only use for that purpose since otherwise it will create a duplicate def.
2123    #[instrument(level = "debug", skip(self))]
2124    fn lower_const_path_to_const_arg(
2125        &mut self,
2126        path: &Path,
2127        res: Res<NodeId>,
2128        ty_id: NodeId,
2129        span: Span,
2130    ) -> &'hir hir::ConstArg<'hir> {
2131        let tcx = self.tcx;
2132
2133        let ct_kind = if path
2134            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2135            && (tcx.features().min_generic_const_args()
2136                || matches!(res, Res::Def(DefKind::ConstParam, _)))
2137        {
2138            let qpath = self.lower_qpath(
2139                ty_id,
2140                &None,
2141                path,
2142                ParamMode::Explicit,
2143                AllowReturnTypeNotation::No,
2144                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2145                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2146                None,
2147            );
2148            hir::ConstArgKind::Path(qpath)
2149        } else {
2150            // Construct an AnonConst where the expr is the "ty"'s path.
2151            let node_id = self.next_node_id();
2152            let span = self.lower_span(span);
2153
2154            // Add a definition for the in-band const def.
2155            // We're lowering a const argument that was originally thought to be a type argument,
2156            // so the def collector didn't create the def ahead of time. That's why we have to do
2157            // it here.
2158            let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2159            let hir_id = self.lower_node_id(node_id);
2160
2161            let path_expr = Expr {
2162                id: ty_id,
2163                kind: ExprKind::Path(None, path.clone()),
2164                span,
2165                attrs: AttrVec::new(),
2166                tokens: None,
2167            };
2168
2169            let ct = self.with_new_scopes(span, |this| {
2170                self.arena.alloc(hir::AnonConst {
2171                    def_id,
2172                    hir_id,
2173                    body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2174                    span,
2175                })
2176            });
2177            hir::ConstArgKind::Anon(ct)
2178        };
2179
2180        self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2181    }
2182
2183    /// See [`hir::ConstArg`] for when to use this function vs
2184    /// [`Self::lower_anon_const_to_anon_const`].
2185    fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2186        self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2187    }
2188
2189    #[instrument(level = "debug", skip(self))]
2190    fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2191        let tcx = self.tcx;
2192        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
2193        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
2194        let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2195            && let [stmt] = block.stmts.as_slice()
2196            && let StmtKind::Expr(expr) = &stmt.kind
2197            && let ExprKind::Path(..) = &expr.kind
2198        {
2199            expr
2200        } else {
2201            &anon.value
2202        };
2203        let maybe_res =
2204            self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2205        if let ExprKind::Path(qself, path) = &expr.kind
2206            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2207            && (tcx.features().min_generic_const_args()
2208                || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2209        {
2210            let qpath = self.lower_qpath(
2211                expr.id,
2212                qself,
2213                path,
2214                ParamMode::Explicit,
2215                AllowReturnTypeNotation::No,
2216                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2217                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2218                None,
2219            );
2220
2221            return ConstArg {
2222                hir_id: self.lower_node_id(anon.id),
2223                kind: hir::ConstArgKind::Path(qpath),
2224            };
2225        }
2226
2227        let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2228        ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2229    }
2230
2231    /// See [`hir::ConstArg`] for when to use this function vs
2232    /// [`Self::lower_anon_const_to_const_arg`].
2233    fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2234        self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2235            let def_id = this.local_def_id(c.id);
2236            let hir_id = this.lower_node_id(c.id);
2237            hir::AnonConst {
2238                def_id,
2239                hir_id,
2240                body: this.lower_const_body(c.value.span, Some(&c.value)),
2241                span: this.lower_span(c.value.span),
2242            }
2243        }))
2244    }
2245
2246    fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2247        match u {
2248            CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2249            UserProvided => hir::UnsafeSource::UserProvided,
2250        }
2251    }
2252
2253    fn lower_trait_bound_modifiers(
2254        &mut self,
2255        modifiers: TraitBoundModifiers,
2256    ) -> hir::TraitBoundModifiers {
2257        hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2258    }
2259
2260    // Helper methods for building HIR.
2261
2262    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2263        hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2264    }
2265
2266    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2267        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2268    }
2269
2270    fn stmt_let_pat(
2271        &mut self,
2272        attrs: Option<&'hir [hir::Attribute]>,
2273        span: Span,
2274        init: Option<&'hir hir::Expr<'hir>>,
2275        pat: &'hir hir::Pat<'hir>,
2276        source: hir::LocalSource,
2277    ) -> hir::Stmt<'hir> {
2278        let hir_id = self.next_id();
2279        if let Some(a) = attrs {
2280            assert!(!a.is_empty());
2281            self.attrs.insert(hir_id.local_id, a);
2282        }
2283        let local = hir::LetStmt {
2284            super_: None,
2285            hir_id,
2286            init,
2287            pat,
2288            els: None,
2289            source,
2290            span: self.lower_span(span),
2291            ty: None,
2292        };
2293        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2294    }
2295
2296    fn stmt_super_let_pat(
2297        &mut self,
2298        span: Span,
2299        pat: &'hir hir::Pat<'hir>,
2300        init: Option<&'hir hir::Expr<'hir>>,
2301    ) -> hir::Stmt<'hir> {
2302        let hir_id = self.next_id();
2303        let local = hir::LetStmt {
2304            super_: Some(span),
2305            hir_id,
2306            init,
2307            pat,
2308            els: None,
2309            source: hir::LocalSource::Normal,
2310            span: self.lower_span(span),
2311            ty: None,
2312        };
2313        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2314    }
2315
2316    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2317        self.block_all(expr.span, &[], Some(expr))
2318    }
2319
2320    fn block_all(
2321        &mut self,
2322        span: Span,
2323        stmts: &'hir [hir::Stmt<'hir>],
2324        expr: Option<&'hir hir::Expr<'hir>>,
2325    ) -> &'hir hir::Block<'hir> {
2326        let blk = hir::Block {
2327            stmts,
2328            expr,
2329            hir_id: self.next_id(),
2330            rules: hir::BlockCheckMode::DefaultBlock,
2331            span: self.lower_span(span),
2332            targeted_by_break: false,
2333        };
2334        self.arena.alloc(blk)
2335    }
2336
2337    fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2338        let field = self.single_pat_field(span, pat);
2339        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2340    }
2341
2342    fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2343        let field = self.single_pat_field(span, pat);
2344        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2345    }
2346
2347    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2348        let field = self.single_pat_field(span, pat);
2349        self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2350    }
2351
2352    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2353        self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2354    }
2355
2356    fn single_pat_field(
2357        &mut self,
2358        span: Span,
2359        pat: &'hir hir::Pat<'hir>,
2360    ) -> &'hir [hir::PatField<'hir>] {
2361        let field = hir::PatField {
2362            hir_id: self.next_id(),
2363            ident: Ident::new(sym::integer(0), self.lower_span(span)),
2364            is_shorthand: false,
2365            pat,
2366            span: self.lower_span(span),
2367        };
2368        arena_vec![self; field]
2369    }
2370
2371    fn pat_lang_item_variant(
2372        &mut self,
2373        span: Span,
2374        lang_item: hir::LangItem,
2375        fields: &'hir [hir::PatField<'hir>],
2376    ) -> &'hir hir::Pat<'hir> {
2377        let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2378        self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2379    }
2380
2381    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2382        self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2383    }
2384
2385    fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2386        self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2387    }
2388
2389    fn pat_ident_binding_mode(
2390        &mut self,
2391        span: Span,
2392        ident: Ident,
2393        bm: hir::BindingMode,
2394    ) -> (&'hir hir::Pat<'hir>, HirId) {
2395        let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2396        (self.arena.alloc(pat), hir_id)
2397    }
2398
2399    fn pat_ident_binding_mode_mut(
2400        &mut self,
2401        span: Span,
2402        ident: Ident,
2403        bm: hir::BindingMode,
2404    ) -> (hir::Pat<'hir>, HirId) {
2405        let hir_id = self.next_id();
2406
2407        (
2408            hir::Pat {
2409                hir_id,
2410                kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2411                span: self.lower_span(span),
2412                default_binding_modes: true,
2413            },
2414            hir_id,
2415        )
2416    }
2417
2418    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2419        self.arena.alloc(hir::Pat {
2420            hir_id: self.next_id(),
2421            kind,
2422            span: self.lower_span(span),
2423            default_binding_modes: true,
2424        })
2425    }
2426
2427    fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2428        hir::Pat {
2429            hir_id: self.next_id(),
2430            kind,
2431            span: self.lower_span(span),
2432            default_binding_modes: false,
2433        }
2434    }
2435
2436    fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2437        let kind = match qpath {
2438            hir::QPath::Resolved(None, path) => {
2439                // Turn trait object paths into `TyKind::TraitObject` instead.
2440                match path.res {
2441                    Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2442                        let principal = hir::PolyTraitRef {
2443                            bound_generic_params: &[],
2444                            modifiers: hir::TraitBoundModifiers::NONE,
2445                            trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2446                            span: self.lower_span(span),
2447                        };
2448
2449                        // The original ID is taken by the `PolyTraitRef`,
2450                        // so the `Ty` itself needs a different one.
2451                        hir_id = self.next_id();
2452                        hir::TyKind::TraitObject(
2453                            arena_vec![self; principal],
2454                            TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2455                        )
2456                    }
2457                    _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2458                }
2459            }
2460            _ => hir::TyKind::Path(qpath),
2461        };
2462
2463        hir::Ty { hir_id, kind, span: self.lower_span(span) }
2464    }
2465
2466    /// Invoked to create the lifetime argument(s) for an elided trait object
2467    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2468    /// when the bound is written, even if it is written with `'_` like in
2469    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2470    fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2471        let r = hir::Lifetime::new(
2472            self.next_id(),
2473            Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2474            hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2475            LifetimeSource::Other,
2476            LifetimeSyntax::Implicit,
2477        );
2478        debug!("elided_dyn_bound: r={:?}", r);
2479        self.arena.alloc(r)
2480    }
2481}
2482
2483/// Helper struct for the delayed construction of [`hir::GenericArgs`].
2484struct GenericArgsCtor<'hir> {
2485    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2486    constraints: &'hir [hir::AssocItemConstraint<'hir>],
2487    parenthesized: hir::GenericArgsParentheses,
2488    span: Span,
2489}
2490
2491impl<'hir> GenericArgsCtor<'hir> {
2492    fn is_empty(&self) -> bool {
2493        self.args.is_empty()
2494            && self.constraints.is_empty()
2495            && self.parenthesized == hir::GenericArgsParentheses::No
2496    }
2497
2498    fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2499        let ga = hir::GenericArgs {
2500            args: this.arena.alloc_from_iter(self.args),
2501            constraints: self.constraints,
2502            parenthesized: self.parenthesized,
2503            span_ext: this.lower_span(self.span),
2504        };
2505        this.arena.alloc(ga)
2506    }
2507}