rustc_ast_lowering/
lib.rs

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