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