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