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