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