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