rustc_ast_lowering/
lib.rs

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