rustc_ast_lowering/
lib.rs

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