rustc_ast_lowering/
lib.rs

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