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