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))]
878    #[inline]
879    fn lower_lifetime_binder(
880        &mut self,
881        binder: NodeId,
882        generic_params: &[GenericParam],
883    ) -> &'hir [hir::GenericParam<'hir>] {
884        let mut generic_params: Vec<_> = self
885            .lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
886            .collect();
887        let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
888        debug!(?extra_lifetimes);
889        generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
890            self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
891        }));
892        let generic_params = self.arena.alloc_from_iter(generic_params);
893        debug!(?generic_params);
894
895        generic_params
896    }
897
898    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
899        let was_in_dyn_type = self.is_in_dyn_type;
900        self.is_in_dyn_type = in_scope;
901
902        let result = f(self);
903
904        self.is_in_dyn_type = was_in_dyn_type;
905
906        result
907    }
908
909    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
910        let current_item = self.current_item;
911        self.current_item = Some(scope_span);
912
913        let was_in_loop_condition = self.is_in_loop_condition;
914        self.is_in_loop_condition = false;
915
916        let old_contract = self.contract_ensures.take();
917
918        let catch_scope = self.catch_scope.take();
919        let loop_scope = self.loop_scope.take();
920        let ret = f(self);
921        self.catch_scope = catch_scope;
922        self.loop_scope = loop_scope;
923
924        self.contract_ensures = old_contract;
925
926        self.is_in_loop_condition = was_in_loop_condition;
927
928        self.current_item = current_item;
929
930        ret
931    }
932
933    fn lower_attrs(
934        &mut self,
935        id: HirId,
936        attrs: &[Attribute],
937        target_span: Span,
938    ) -> &'hir [hir::Attribute] {
939        if attrs.is_empty() {
940            &[]
941        } else {
942            let lowered_attrs = self.lower_attrs_vec(attrs, self.lower_span(target_span), id);
943
944            assert_eq!(id.owner, self.current_hir_id_owner);
945            let ret = self.arena.alloc_from_iter(lowered_attrs);
946
947            // this is possible if an item contained syntactical attribute,
948            // but none of them parse successfully or all of them were ignored
949            // for not being built-in attributes at all. They could be remaining
950            // unexpanded attributes used as markers in proc-macro derives for example.
951            // This will have emitted some diagnostics for the misparse, but will then
952            // not emit the attribute making the list empty.
953            if ret.is_empty() {
954                &[]
955            } else {
956                self.attrs.insert(id.local_id, ret);
957                ret
958            }
959        }
960    }
961
962    fn lower_attrs_vec(
963        &mut self,
964        attrs: &[Attribute],
965        target_span: Span,
966        target_hir_id: HirId,
967    ) -> Vec<hir::Attribute> {
968        let l = self.span_lowerer();
969        self.attribute_parser.parse_attribute_list(
970            attrs,
971            target_span,
972            target_hir_id,
973            OmitDoc::Lower,
974            |s| l.lower(s),
975            |l| {
976                self.delayed_lints.push(DelayedLint::AttributeParsing(l));
977            },
978        )
979    }
980
981    fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
982        assert_eq!(id.owner, self.current_hir_id_owner);
983        assert_eq!(target_id.owner, self.current_hir_id_owner);
984        if let Some(&a) = self.attrs.get(&target_id.local_id) {
985            assert!(!a.is_empty());
986            self.attrs.insert(id.local_id, a);
987        }
988    }
989
990    fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
991        args.clone()
992    }
993
994    /// Lower an associated item constraint.
995    #[instrument(level = "debug", skip_all)]
996    fn lower_assoc_item_constraint(
997        &mut self,
998        constraint: &AssocItemConstraint,
999        itctx: ImplTraitContext,
1000    ) -> hir::AssocItemConstraint<'hir> {
1001        debug!(?constraint, ?itctx);
1002        // Lower the generic arguments for the associated item.
1003        let gen_args = if let Some(gen_args) = &constraint.gen_args {
1004            let gen_args_ctor = match gen_args {
1005                GenericArgs::AngleBracketed(data) => {
1006                    self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
1007                }
1008                GenericArgs::Parenthesized(data) => {
1009                    if let Some(first_char) = constraint.ident.as_str().chars().next()
1010                        && first_char.is_ascii_lowercase()
1011                    {
1012                        let err = match (&data.inputs[..], &data.output) {
1013                            ([_, ..], FnRetTy::Default(_)) => {
1014                                errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
1015                            }
1016                            ([], FnRetTy::Default(_)) => {
1017                                errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }
1018                            }
1019                            // The case `T: Trait<method(..) -> Ret>` is handled in the parser.
1020                            (_, FnRetTy::Ty(ty)) => {
1021                                let span = data.inputs_span.shrink_to_hi().to(ty.span);
1022                                errors::BadReturnTypeNotation::Output {
1023                                    span,
1024                                    suggestion: errors::RTNSuggestion {
1025                                        output: span,
1026                                        input: data.inputs_span,
1027                                    },
1028                                }
1029                            }
1030                        };
1031                        let mut err = self.dcx().create_err(err);
1032                        if !self.tcx.features().return_type_notation()
1033                            && self.tcx.sess.is_nightly_build()
1034                        {
1035                            add_feature_diagnostics(
1036                                &mut err,
1037                                &self.tcx.sess,
1038                                sym::return_type_notation,
1039                            );
1040                        }
1041                        err.emit();
1042                        GenericArgsCtor {
1043                            args: Default::default(),
1044                            constraints: &[],
1045                            parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1046                            span: data.span,
1047                        }
1048                    } else {
1049                        self.emit_bad_parenthesized_trait_in_assoc_ty(data);
1050                        // FIXME(return_type_notation): we could issue a feature error
1051                        // if the parens are empty and there's no return type.
1052                        self.lower_angle_bracketed_parameter_data(
1053                            &data.as_angle_bracketed_args(),
1054                            ParamMode::Explicit,
1055                            itctx,
1056                        )
1057                        .0
1058                    }
1059                }
1060                GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {
1061                    args: Default::default(),
1062                    constraints: &[],
1063                    parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
1064                    span: *span,
1065                },
1066            };
1067            gen_args_ctor.into_generic_args(self)
1068        } else {
1069            self.arena.alloc(hir::GenericArgs::none())
1070        };
1071        let kind = match &constraint.kind {
1072            AssocItemConstraintKind::Equality { term } => {
1073                let term = match term {
1074                    Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
1075                    Term::Const(c) => self.lower_anon_const_to_const_arg(c).into(),
1076                };
1077                hir::AssocItemConstraintKind::Equality { term }
1078            }
1079            AssocItemConstraintKind::Bound { bounds } => {
1080                // Disallow ATB in dyn types
1081                if self.is_in_dyn_type {
1082                    let suggestion = match itctx {
1083                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
1084                            let bound_end_span = constraint
1085                                .gen_args
1086                                .as_ref()
1087                                .map_or(constraint.ident.span, |args| args.span());
1088                            if bound_end_span.eq_ctxt(constraint.span) {
1089                                Some(self.tcx.sess.source_map().next_point(bound_end_span))
1090                            } else {
1091                                None
1092                            }
1093                        }
1094                        _ => None,
1095                    };
1096
1097                    let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1098                        span: constraint.span,
1099                        suggestion,
1100                    });
1101                    let err_ty =
1102                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
1103                    hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
1104                } else {
1105                    // FIXME(#135229): These should be forbidden!
1106                    let bounds =
1107                        self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx);
1108                    hir::AssocItemConstraintKind::Bound { bounds }
1109                }
1110            }
1111        };
1112
1113        hir::AssocItemConstraint {
1114            hir_id: self.lower_node_id(constraint.id),
1115            ident: self.lower_ident(constraint.ident),
1116            gen_args,
1117            kind,
1118            span: self.lower_span(constraint.span),
1119        }
1120    }
1121
1122    fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1123        // Suggest removing empty parentheses: "Trait()" -> "Trait"
1124        let sub = if data.inputs.is_empty() {
1125            let parentheses_span =
1126                data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1127            AssocTyParenthesesSub::Empty { parentheses_span }
1128        }
1129        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1130        else {
1131            // Start of parameters to the 1st argument
1132            let open_param = data.inputs_span.shrink_to_lo().to(data
1133                .inputs
1134                .first()
1135                .unwrap()
1136                .span
1137                .shrink_to_lo());
1138            // End of last argument to end of parameters
1139            let close_param =
1140                data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1141            AssocTyParenthesesSub::NotEmpty { open_param, close_param }
1142        };
1143        self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });
1144    }
1145
1146    #[instrument(level = "debug", skip(self))]
1147    fn lower_generic_arg(
1148        &mut self,
1149        arg: &ast::GenericArg,
1150        itctx: ImplTraitContext,
1151    ) -> hir::GenericArg<'hir> {
1152        match arg {
1153            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(
1154                lt,
1155                LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },
1156                lt.ident.into(),
1157            )),
1158            ast::GenericArg::Type(ty) => {
1159                // We cannot just match on `TyKind::Infer` as `(_)` is represented as
1160                // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`
1161                if ty.is_maybe_parenthesised_infer() {
1162                    return GenericArg::Infer(hir::InferArg {
1163                        hir_id: self.lower_node_id(ty.id),
1164                        span: self.lower_span(ty.span),
1165                    });
1166                }
1167
1168                match &ty.kind {
1169                    // We parse const arguments as path types as we cannot distinguish them during
1170                    // parsing. We try to resolve that ambiguity by attempting resolution in both the
1171                    // type and value namespaces. If we resolved the path in the value namespace, we
1172                    // transform it into a generic const argument.
1173                    //
1174                    // FIXME: Should we be handling `(PATH_TO_CONST)`?
1175                    TyKind::Path(None, path) => {
1176                        if let Some(res) = self
1177                            .resolver
1178                            .get_partial_res(ty.id)
1179                            .and_then(|partial_res| partial_res.full_res())
1180                        {
1181                            if !res.matches_ns(Namespace::TypeNS)
1182                                && path.is_potential_trivial_const_arg(false)
1183                            {
1184                                debug!(
1185                                    "lower_generic_arg: Lowering type argument as const argument: {:?}",
1186                                    ty,
1187                                );
1188
1189                                let ct =
1190                                    self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1191                                return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
1192                            }
1193                        }
1194                    }
1195                    _ => {}
1196                }
1197                GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1198            }
1199            ast::GenericArg::Const(ct) => {
1200                GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
1201            }
1202        }
1203    }
1204
1205    #[instrument(level = "debug", skip(self))]
1206    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1207        self.arena.alloc(self.lower_ty_direct(t, itctx))
1208    }
1209
1210    fn lower_path_ty(
1211        &mut self,
1212        t: &Ty,
1213        qself: &Option<ptr::P<QSelf>>,
1214        path: &Path,
1215        param_mode: ParamMode,
1216        itctx: ImplTraitContext,
1217    ) -> hir::Ty<'hir> {
1218        // Check whether we should interpret this as a bare trait object.
1219        // This check mirrors the one in late resolution. We only introduce this special case in
1220        // the rare occurrence we need to lower `Fresh` anonymous lifetimes.
1221        // The other cases when a qpath should be opportunistically made a trait object are handled
1222        // by `ty_path`.
1223        if qself.is_none()
1224            && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1225            && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
1226        {
1227            let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1228                let bound = this.lower_poly_trait_ref(
1229                    &PolyTraitRef {
1230                        bound_generic_params: ThinVec::new(),
1231                        modifiers: TraitBoundModifiers::NONE,
1232                        trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1233                        span: t.span,
1234                        parens: ast::Parens::No,
1235                    },
1236                    RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),
1237                    itctx,
1238                );
1239                let bounds = this.arena.alloc_from_iter([bound]);
1240                let lifetime_bound = this.elided_dyn_bound(t.span);
1241                (bounds, lifetime_bound)
1242            });
1243            let kind = hir::TyKind::TraitObject(
1244                bounds,
1245                TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),
1246            );
1247            return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1248        }
1249
1250        let id = self.lower_node_id(t.id);
1251        let qpath = self.lower_qpath(
1252            t.id,
1253            qself,
1254            path,
1255            param_mode,
1256            AllowReturnTypeNotation::Yes,
1257            itctx,
1258            None,
1259        );
1260        self.ty_path(id, t.span, qpath)
1261    }
1262
1263    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1264        hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1265    }
1266
1267    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1268        self.ty(span, hir::TyKind::Tup(tys))
1269    }
1270
1271    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1272        let kind = match &t.kind {
1273            TyKind::Infer => hir::TyKind::Infer(()),
1274            TyKind::Err(guar) => hir::TyKind::Err(*guar),
1275            TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1276            TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1277            TyKind::Ref(region, mt) => {
1278                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1279                hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
1280            }
1281            TyKind::PinnedRef(region, mt) => {
1282                let lifetime = self.lower_ty_direct_lifetime(t, *region);
1283                let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
1284                let span = self.lower_span(t.span);
1285                let arg = hir::Ty { kind, span, hir_id: self.next_id() };
1286                let args = self.arena.alloc(hir::GenericArgs {
1287                    args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
1288                    constraints: &[],
1289                    parenthesized: hir::GenericArgsParentheses::No,
1290                    span_ext: span,
1291                });
1292                let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));
1293                hir::TyKind::Path(path)
1294            }
1295            TyKind::FnPtr(f) => {
1296                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1297                hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {
1298                    generic_params,
1299                    safety: self.lower_safety(f.safety, hir::Safety::Safe),
1300                    abi: self.lower_extern(f.ext),
1301                    decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
1302                    param_idents: self.lower_fn_params_to_idents(&f.decl),
1303                }))
1304            }
1305            TyKind::UnsafeBinder(f) => {
1306                let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
1307                hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {
1308                    generic_params,
1309                    inner_ty: self.lower_ty(&f.inner_ty, itctx),
1310                }))
1311            }
1312            TyKind::Never => hir::TyKind::Never,
1313            TyKind::Tup(tys) => hir::TyKind::Tup(
1314                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1315            ),
1316            TyKind::Paren(ty) => {
1317                return self.lower_ty_direct(ty, itctx);
1318            }
1319            TyKind::Path(qself, path) => {
1320                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1321            }
1322            TyKind::ImplicitSelf => {
1323                let hir_id = self.next_id();
1324                let res = self.expect_full_res(t.id);
1325                let res = self.lower_res(res);
1326                hir::TyKind::Path(hir::QPath::Resolved(
1327                    None,
1328                    self.arena.alloc(hir::Path {
1329                        res,
1330                        segments: arena_vec![self; hir::PathSegment::new(
1331                            Ident::with_dummy_span(kw::SelfUpper),
1332                            hir_id,
1333                            res
1334                        )],
1335                        span: self.lower_span(t.span),
1336                    }),
1337                ))
1338            }
1339            TyKind::Array(ty, length) => hir::TyKind::Array(
1340                self.lower_ty(ty, itctx),
1341                self.lower_array_length_to_const_arg(length),
1342            ),
1343            TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)),
1344            TyKind::TraitObject(bounds, kind) => {
1345                let mut lifetime_bound = None;
1346                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1347                    let bounds =
1348                        this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
1349                            // We can safely ignore constness here since AST validation
1350                            // takes care of rejecting invalid modifier combinations and
1351                            // const trait bounds in trait object types.
1352                            GenericBound::Trait(ty) => {
1353                                let trait_ref = this.lower_poly_trait_ref(
1354                                    ty,
1355                                    RelaxedBoundPolicy::Forbidden(
1356                                        RelaxedBoundForbiddenReason::TraitObjectTy,
1357                                    ),
1358                                    itctx,
1359                                );
1360                                Some(trait_ref)
1361                            }
1362                            GenericBound::Outlives(lifetime) => {
1363                                if lifetime_bound.is_none() {
1364                                    lifetime_bound = Some(this.lower_lifetime(
1365                                        lifetime,
1366                                        LifetimeSource::Other,
1367                                        lifetime.ident.into(),
1368                                    ));
1369                                }
1370                                None
1371                            }
1372                            // Ignore `use` syntax since that is not valid in objects.
1373                            GenericBound::Use(_, span) => {
1374                                this.dcx()
1375                                    .span_delayed_bug(*span, "use<> not allowed in dyn types");
1376                                None
1377                            }
1378                        }));
1379                    let lifetime_bound =
1380                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1381                    (bounds, lifetime_bound)
1382                });
1383                hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))
1384            }
1385            TyKind::ImplTrait(def_node_id, bounds) => {
1386                let span = t.span;
1387                match itctx {
1388                    ImplTraitContext::OpaqueTy { origin } => {
1389                        self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)
1390                    }
1391                    ImplTraitContext::Universal => {
1392                        if let Some(span) = bounds.iter().find_map(|bound| match *bound {
1393                            ast::GenericBound::Use(_, span) => Some(span),
1394                            _ => None,
1395                        }) {
1396                            self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });
1397                        }
1398
1399                        let def_id = self.local_def_id(*def_node_id);
1400                        let name = self.tcx.item_name(def_id.to_def_id());
1401                        let ident = Ident::new(name, span);
1402                        let (param, bounds, path) = self.lower_universal_param_and_bounds(
1403                            *def_node_id,
1404                            span,
1405                            ident,
1406                            bounds,
1407                        );
1408                        self.impl_trait_defs.push(param);
1409                        if let Some(bounds) = bounds {
1410                            self.impl_trait_bounds.push(bounds);
1411                        }
1412                        path
1413                    }
1414                    ImplTraitContext::InBinding => hir::TyKind::TraitAscription(
1415                        self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),
1416                    ),
1417                    ImplTraitContext::FeatureGated(position, feature) => {
1418                        let guar = self
1419                            .tcx
1420                            .sess
1421                            .create_feature_err(
1422                                MisplacedImplTrait {
1423                                    span: t.span,
1424                                    position: DiagArgFromDisplay(&position),
1425                                },
1426                                feature,
1427                            )
1428                            .emit();
1429                        hir::TyKind::Err(guar)
1430                    }
1431                    ImplTraitContext::Disallowed(position) => {
1432                        let guar = self.dcx().emit_err(MisplacedImplTrait {
1433                            span: t.span,
1434                            position: DiagArgFromDisplay(&position),
1435                        });
1436                        hir::TyKind::Err(guar)
1437                    }
1438                }
1439            }
1440            TyKind::Pat(ty, pat) => {
1441                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
1442            }
1443            TyKind::MacCall(_) => {
1444                span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
1445            }
1446            TyKind::CVarArgs => {
1447                let guar = self.dcx().span_delayed_bug(
1448                    t.span,
1449                    "`TyKind::CVarArgs` should have been handled elsewhere",
1450                );
1451                hir::TyKind::Err(guar)
1452            }
1453            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
1454        };
1455
1456        hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1457    }
1458
1459    fn lower_ty_direct_lifetime(
1460        &mut self,
1461        t: &Ty,
1462        region: Option<Lifetime>,
1463    ) -> &'hir hir::Lifetime {
1464        let (region, syntax) = match region {
1465            Some(region) => (region, region.ident.into()),
1466
1467            None => {
1468                let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1469                    self.resolver.get_lifetime_res(t.id)
1470                {
1471                    assert_eq!(start.plus(1), end);
1472                    start
1473                } else {
1474                    self.next_node_id()
1475                };
1476                let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
1477                let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };
1478                (region, LifetimeSyntax::Implicit)
1479            }
1480        };
1481        self.lower_lifetime(&region, LifetimeSource::Reference, syntax)
1482    }
1483
1484    /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1485    /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1486    /// HIR type that references the TAIT.
1487    ///
1488    /// Given a function definition like:
1489    ///
1490    /// ```rust
1491    /// use std::fmt::Debug;
1492    ///
1493    /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1494    ///     x
1495    /// }
1496    /// ```
1497    ///
1498    /// we will create a TAIT definition in the HIR like
1499    ///
1500    /// ```rust,ignore (pseudo-Rust)
1501    /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1502    /// ```
1503    ///
1504    /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1505    ///
1506    /// ```rust,ignore (pseudo-Rust)
1507    /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1508    /// ```
1509    ///
1510    /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1511    /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1512    /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1513    /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1514    /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1515    #[instrument(level = "debug", skip(self), ret)]
1516    fn lower_opaque_impl_trait(
1517        &mut self,
1518        span: Span,
1519        origin: hir::OpaqueTyOrigin<LocalDefId>,
1520        opaque_ty_node_id: NodeId,
1521        bounds: &GenericBounds,
1522        itctx: ImplTraitContext,
1523    ) -> hir::TyKind<'hir> {
1524        // Make sure we know that some funky desugaring has been going on here.
1525        // This is a first: there is code in other places like for loop
1526        // desugaring that explicitly states that we don't want to track that.
1527        // Not tracking it makes lints in rustc and clippy very fragile, as
1528        // frequently opened issues show.
1529        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1530
1531        self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
1532            this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)
1533        })
1534    }
1535
1536    fn lower_opaque_inner(
1537        &mut self,
1538        opaque_ty_node_id: NodeId,
1539        origin: hir::OpaqueTyOrigin<LocalDefId>,
1540        opaque_ty_span: Span,
1541        lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],
1542    ) -> hir::TyKind<'hir> {
1543        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1544        let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);
1545        debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);
1546
1547        let bounds = lower_item_bounds(self);
1548        let opaque_ty_def = hir::OpaqueTy {
1549            hir_id: opaque_ty_hir_id,
1550            def_id: opaque_ty_def_id,
1551            bounds,
1552            origin,
1553            span: self.lower_span(opaque_ty_span),
1554        };
1555        let opaque_ty_def = self.arena.alloc(opaque_ty_def);
1556
1557        hir::TyKind::OpaqueDef(opaque_ty_def)
1558    }
1559
1560    fn lower_precise_capturing_args(
1561        &mut self,
1562        precise_capturing_args: &[PreciseCapturingArg],
1563    ) -> &'hir [hir::PreciseCapturingArg<'hir>] {
1564        self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {
1565            PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(
1566                self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),
1567            ),
1568            PreciseCapturingArg::Arg(path, id) => {
1569                let [segment] = path.segments.as_slice() else {
1570                    panic!();
1571                };
1572                let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
1573                    partial_res.full_res().expect("no partial res expected for precise capture arg")
1574                });
1575                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1576                    hir_id: self.lower_node_id(*id),
1577                    ident: self.lower_ident(segment.ident),
1578                    res: self.lower_res(res),
1579                })
1580            }
1581        }))
1582    }
1583
1584    fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
1585        self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
1586            PatKind::Missing => None,
1587            PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),
1588            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
1589            _ => {
1590                self.dcx().span_delayed_bug(
1591                    param.pat.span,
1592                    "non-missing/ident/wild param pat must trigger an error",
1593                );
1594                None
1595            }
1596        }))
1597    }
1598
1599    /// Lowers a function declaration.
1600    ///
1601    /// `decl`: the unlowered (AST) function declaration.
1602    ///
1603    /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given
1604    /// `NodeId`.
1605    ///
1606    /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is
1607    /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.
1608    #[instrument(level = "debug", skip(self))]
1609    fn lower_fn_decl(
1610        &mut self,
1611        decl: &FnDecl,
1612        fn_node_id: NodeId,
1613        fn_span: Span,
1614        kind: FnDeclKind,
1615        coro: Option<CoroutineKind>,
1616    ) -> &'hir hir::FnDecl<'hir> {
1617        let c_variadic = decl.c_variadic();
1618
1619        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1620        // as they are not explicit in HIR/Ty function signatures.
1621        // (instead, the `c_variadic` flag is set to `true`)
1622        let mut inputs = &decl.inputs[..];
1623        if c_variadic {
1624            inputs = &inputs[..inputs.len() - 1];
1625        }
1626        let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1627            let itctx = match kind {
1628                FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
1629                    ImplTraitContext::Universal
1630                }
1631                FnDeclKind::ExternFn => {
1632                    ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
1633                }
1634                FnDeclKind::Closure => {
1635                    ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
1636                }
1637                FnDeclKind::Pointer => {
1638                    ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
1639                }
1640            };
1641            self.lower_ty_direct(&param.ty, itctx)
1642        }));
1643
1644        let output = match coro {
1645            Some(coro) => {
1646                let fn_def_id = self.local_def_id(fn_node_id);
1647                self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind, fn_span)
1648            }
1649            None => match &decl.output {
1650                FnRetTy::Ty(ty) => {
1651                    let itctx = match kind {
1652                        FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {
1653                            origin: hir::OpaqueTyOrigin::FnReturn {
1654                                parent: self.local_def_id(fn_node_id),
1655                                in_trait_or_impl: None,
1656                            },
1657                        },
1658                        FnDeclKind::Trait => ImplTraitContext::OpaqueTy {
1659                            origin: hir::OpaqueTyOrigin::FnReturn {
1660                                parent: self.local_def_id(fn_node_id),
1661                                in_trait_or_impl: Some(hir::RpitContext::Trait),
1662                            },
1663                        },
1664                        FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
1665                            origin: hir::OpaqueTyOrigin::FnReturn {
1666                                parent: self.local_def_id(fn_node_id),
1667                                in_trait_or_impl: Some(hir::RpitContext::TraitImpl),
1668                            },
1669                        },
1670                        FnDeclKind::ExternFn => {
1671                            ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
1672                        }
1673                        FnDeclKind::Closure => {
1674                            ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
1675                        }
1676                        FnDeclKind::Pointer => {
1677                            ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
1678                        }
1679                    };
1680                    hir::FnRetTy::Return(self.lower_ty(ty, itctx))
1681                }
1682                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
1683            },
1684        };
1685
1686        self.arena.alloc(hir::FnDecl {
1687            inputs,
1688            output,
1689            c_variadic,
1690            lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id),
1691            implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1692                let is_mutable_pat = matches!(
1693                    arg.pat.kind,
1694                    PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)
1695                );
1696
1697                match &arg.ty.kind {
1698                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1699                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1700                    // Given we are only considering `ImplicitSelf` types, we needn't consider
1701                    // the case where we have a mutable pattern to a reference as that would
1702                    // no longer be an `ImplicitSelf`.
1703                    TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1704                        if mt.ty.kind.is_implicit_self() =>
1705                    {
1706                        match mt.mutbl {
1707                            hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
1708                            hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
1709                        }
1710                    }
1711                    _ => hir::ImplicitSelfKind::None,
1712                }
1713            }),
1714        })
1715    }
1716
1717    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1718    // combined with the following definition of `OpaqueTy`:
1719    //
1720    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1721    //
1722    // `output`: unlowered output type (`T` in `-> T`)
1723    // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)
1724    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1725    #[instrument(level = "debug", skip(self))]
1726    fn lower_coroutine_fn_ret_ty(
1727        &mut self,
1728        output: &FnRetTy,
1729        fn_def_id: LocalDefId,
1730        coro: CoroutineKind,
1731        fn_kind: FnDeclKind,
1732        fn_span: Span,
1733    ) -> hir::FnRetTy<'hir> {
1734        let span = self.lower_span(fn_span);
1735
1736        let (opaque_ty_node_id, allowed_features) = match coro {
1737            CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1738            CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
1739            CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
1740                (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))
1741            }
1742        };
1743
1744        let opaque_ty_span =
1745            self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);
1746
1747        let in_trait_or_impl = match fn_kind {
1748            FnDeclKind::Trait => Some(hir::RpitContext::Trait),
1749            FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),
1750            FnDeclKind::Fn | FnDeclKind::Inherent => None,
1751            FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),
1752        };
1753
1754        let opaque_ty_ref = self.lower_opaque_inner(
1755            opaque_ty_node_id,
1756            hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
1757            opaque_ty_span,
1758            |this| {
1759                let bound = this.lower_coroutine_fn_output_type_to_bound(
1760                    output,
1761                    coro,
1762                    opaque_ty_span,
1763                    ImplTraitContext::OpaqueTy {
1764                        origin: hir::OpaqueTyOrigin::FnReturn {
1765                            parent: fn_def_id,
1766                            in_trait_or_impl,
1767                        },
1768                    },
1769                );
1770                arena_vec![this; bound]
1771            },
1772        );
1773
1774        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1775        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1776    }
1777
1778    /// Transforms `-> T` into `Future<Output = T>`.
1779    fn lower_coroutine_fn_output_type_to_bound(
1780        &mut self,
1781        output: &FnRetTy,
1782        coro: CoroutineKind,
1783        opaque_ty_span: Span,
1784        itctx: ImplTraitContext,
1785    ) -> hir::GenericBound<'hir> {
1786        // Compute the `T` in `Future<Output = T>` from the return type.
1787        let output_ty = match output {
1788            FnRetTy::Ty(ty) => {
1789                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1790                // `impl Future` opaque type that `async fn` implicitly
1791                // generates.
1792                self.lower_ty(ty, itctx)
1793            }
1794            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1795        };
1796
1797        // "<$assoc_ty_name = T>"
1798        let (assoc_ty_name, trait_lang_item) = match coro {
1799            CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),
1800            CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),
1801            CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
1802        };
1803
1804        let bound_args = self.arena.alloc(hir::GenericArgs {
1805            args: &[],
1806            constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
1807            parenthesized: hir::GenericArgsParentheses::No,
1808            span_ext: DUMMY_SP,
1809        });
1810
1811        hir::GenericBound::Trait(hir::PolyTraitRef {
1812            bound_generic_params: &[],
1813            modifiers: hir::TraitBoundModifiers::NONE,
1814            trait_ref: hir::TraitRef {
1815                path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),
1816                hir_ref_id: self.next_id(),
1817            },
1818            span: opaque_ty_span,
1819        })
1820    }
1821
1822    #[instrument(level = "trace", skip(self))]
1823    fn lower_param_bound(
1824        &mut self,
1825        tpb: &GenericBound,
1826        rbp: RelaxedBoundPolicy<'_>,
1827        itctx: ImplTraitContext,
1828    ) -> hir::GenericBound<'hir> {
1829        match tpb {
1830            GenericBound::Trait(p) => {
1831                hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))
1832            }
1833            GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
1834                lifetime,
1835                LifetimeSource::OutlivesBound,
1836                lifetime.ident.into(),
1837            )),
1838            GenericBound::Use(args, span) => hir::GenericBound::Use(
1839                self.lower_precise_capturing_args(args),
1840                self.lower_span(*span),
1841            ),
1842        }
1843    }
1844
1845    fn lower_lifetime(
1846        &mut self,
1847        l: &Lifetime,
1848        source: LifetimeSource,
1849        syntax: LifetimeSyntax,
1850    ) -> &'hir hir::Lifetime {
1851        self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)
1852    }
1853
1854    fn lower_lifetime_hidden_in_path(
1855        &mut self,
1856        id: NodeId,
1857        span: Span,
1858        angle_brackets: AngleBrackets,
1859    ) -> &'hir hir::Lifetime {
1860        self.new_named_lifetime(
1861            id,
1862            id,
1863            Ident::new(kw::UnderscoreLifetime, span),
1864            LifetimeSource::Path { angle_brackets },
1865            LifetimeSyntax::Implicit,
1866        )
1867    }
1868
1869    #[instrument(level = "debug", skip(self))]
1870    fn new_named_lifetime(
1871        &mut self,
1872        id: NodeId,
1873        new_id: NodeId,
1874        ident: Ident,
1875        source: LifetimeSource,
1876        syntax: LifetimeSyntax,
1877    ) -> &'hir hir::Lifetime {
1878        let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
1879        let res = match res {
1880            LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
1881            LifetimeRes::Fresh { param, .. } => {
1882                assert_eq!(ident.name, kw::UnderscoreLifetime);
1883                let param = self.local_def_id(param);
1884                hir::LifetimeKind::Param(param)
1885            }
1886            LifetimeRes::Infer => {
1887                assert_eq!(ident.name, kw::UnderscoreLifetime);
1888                hir::LifetimeKind::Infer
1889            }
1890            LifetimeRes::Static { .. } => {
1891                assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
1892                hir::LifetimeKind::Static
1893            }
1894            LifetimeRes::Error => hir::LifetimeKind::Error,
1895            LifetimeRes::ElidedAnchor { .. } => {
1896                panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
1897            }
1898        };
1899
1900        debug!(?res);
1901        self.arena.alloc(hir::Lifetime::new(
1902            self.lower_node_id(new_id),
1903            self.lower_ident(ident),
1904            res,
1905            source,
1906            syntax,
1907        ))
1908    }
1909
1910    fn lower_generic_params_mut(
1911        &mut self,
1912        params: &[GenericParam],
1913        source: hir::GenericParamSource,
1914    ) -> impl Iterator<Item = hir::GenericParam<'hir>> {
1915        params.iter().map(move |param| self.lower_generic_param(param, source))
1916    }
1917
1918    fn lower_generic_params(
1919        &mut self,
1920        params: &[GenericParam],
1921        source: hir::GenericParamSource,
1922    ) -> &'hir [hir::GenericParam<'hir>] {
1923        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, source))
1924    }
1925
1926    #[instrument(level = "trace", skip(self))]
1927    fn lower_generic_param(
1928        &mut self,
1929        param: &GenericParam,
1930        source: hir::GenericParamSource,
1931    ) -> hir::GenericParam<'hir> {
1932        let (name, kind) = self.lower_generic_param_kind(param, source);
1933
1934        let hir_id = self.lower_node_id(param.id);
1935        self.lower_attrs(hir_id, &param.attrs, param.span());
1936        hir::GenericParam {
1937            hir_id,
1938            def_id: self.local_def_id(param.id),
1939            name,
1940            span: self.lower_span(param.span()),
1941            pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
1942            kind,
1943            colon_span: param.colon_span.map(|s| self.lower_span(s)),
1944            source,
1945        }
1946    }
1947
1948    fn lower_generic_param_kind(
1949        &mut self,
1950        param: &GenericParam,
1951        source: hir::GenericParamSource,
1952    ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1953        match &param.kind {
1954            GenericParamKind::Lifetime => {
1955                // AST resolution emitted an error on those parameters, so we lower them using
1956                // `ParamName::Error`.
1957                let ident = self.lower_ident(param.ident);
1958                let param_name =
1959                    if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1960                        ParamName::Error(ident)
1961                    } else {
1962                        ParamName::Plain(ident)
1963                    };
1964                let kind =
1965                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1966
1967                (param_name, kind)
1968            }
1969            GenericParamKind::Type { default, .. } => {
1970                // Not only do we deny type param defaults in binders but we also map them to `None`
1971                // since later compiler stages cannot handle them (and shouldn't need to be able to).
1972                let default = default
1973                    .as_ref()
1974                    .filter(|_| match source {
1975                        hir::GenericParamSource::Generics => true,
1976                        hir::GenericParamSource::Binder => {
1977                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
1978                                span: param.span(),
1979                            });
1980
1981                            false
1982                        }
1983                    })
1984                    .map(|def| {
1985                        self.lower_ty(
1986                            def,
1987                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
1988                        )
1989                    });
1990
1991                let kind = hir::GenericParamKind::Type { default, synthetic: false };
1992
1993                (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1994            }
1995            GenericParamKind::Const { ty, span: _, default } => {
1996                let ty = self
1997                    .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
1998
1999                // Not only do we deny const param defaults in binders but we also map them to `None`
2000                // since later compiler stages cannot handle them (and shouldn't need to be able to).
2001                let default = default
2002                    .as_ref()
2003                    .filter(|_| match source {
2004                        hir::GenericParamSource::Generics => true,
2005                        hir::GenericParamSource::Binder => {
2006                            self.dcx().emit_err(errors::GenericParamDefaultInBinder {
2007                                span: param.span(),
2008                            });
2009
2010                            false
2011                        }
2012                    })
2013                    .map(|def| self.lower_anon_const_to_const_arg(def));
2014
2015                (
2016                    hir::ParamName::Plain(self.lower_ident(param.ident)),
2017                    hir::GenericParamKind::Const { ty, default, synthetic: false },
2018                )
2019            }
2020        }
2021    }
2022
2023    fn lower_trait_ref(
2024        &mut self,
2025        modifiers: ast::TraitBoundModifiers,
2026        p: &TraitRef,
2027        itctx: ImplTraitContext,
2028    ) -> hir::TraitRef<'hir> {
2029        let path = match self.lower_qpath(
2030            p.ref_id,
2031            &None,
2032            &p.path,
2033            ParamMode::Explicit,
2034            AllowReturnTypeNotation::No,
2035            itctx,
2036            Some(modifiers),
2037        ) {
2038            hir::QPath::Resolved(None, path) => path,
2039            qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2040        };
2041        hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2042    }
2043
2044    #[instrument(level = "debug", skip(self))]
2045    fn lower_poly_trait_ref(
2046        &mut self,
2047        PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
2048        rbp: RelaxedBoundPolicy<'_>,
2049        itctx: ImplTraitContext,
2050    ) -> hir::PolyTraitRef<'hir> {
2051        let bound_generic_params =
2052            self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
2053        let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
2054        let modifiers = self.lower_trait_bound_modifiers(*modifiers);
2055
2056        if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
2057            self.validate_relaxed_bound(trait_ref, *span, rbp);
2058        }
2059
2060        hir::PolyTraitRef {
2061            bound_generic_params,
2062            modifiers,
2063            trait_ref,
2064            span: self.lower_span(*span),
2065        }
2066    }
2067
2068    fn validate_relaxed_bound(
2069        &self,
2070        trait_ref: hir::TraitRef<'_>,
2071        span: Span,
2072        rbp: RelaxedBoundPolicy<'_>,
2073    ) {
2074        // Even though feature `more_maybe_bounds` bypasses the given policy and (currently) enables
2075        // relaxed bounds in every conceivable position[^1], we don't want to advertise it to the user
2076        // (via a feature gate) since it's super internal. Besides this, it'd be quite distracting.
2077        //
2078        // [^1]: Strictly speaking, this is incorrect (at the very least for `Sized`) because it's
2079        //       no longer fully consistent with default trait elaboration in HIR ty lowering.
2080
2081        match rbp {
2082            RelaxedBoundPolicy::Allowed => return,
2083            RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
2084                if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
2085                    && let Res::Def(DefKind::TyParam, def_id) = res
2086                    && params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
2087                {
2088                    return;
2089                }
2090                if self.tcx.features().more_maybe_bounds() {
2091                    return;
2092                }
2093            }
2094            RelaxedBoundPolicy::Forbidden(reason) => {
2095                if self.tcx.features().more_maybe_bounds() {
2096                    return;
2097                }
2098
2099                match reason {
2100                    RelaxedBoundForbiddenReason::TraitObjectTy => {
2101                        self.dcx().span_err(
2102                            span,
2103                            "relaxed bounds are not permitted in trait object types",
2104                        );
2105                        return;
2106                    }
2107                    RelaxedBoundForbiddenReason::SuperTrait => {
2108                        let mut diag = self.dcx().struct_span_err(
2109                            span,
2110                            "relaxed bounds are not permitted in supertrait bounds",
2111                        );
2112                        if let Some(def_id) = trait_ref.trait_def_id()
2113                            && self.tcx.is_lang_item(def_id, hir::LangItem::Sized)
2114                        {
2115                            diag.note("traits are `?Sized` by default");
2116                        }
2117                        diag.emit();
2118                        return;
2119                    }
2120                    RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
2121                };
2122            }
2123        }
2124
2125        self.dcx()
2126            .struct_span_err(span, "this relaxed bound is not permitted here")
2127            .with_note(
2128                "in this context, relaxed bounds are only allowed on \
2129                 type parameters defined by the closest item",
2130            )
2131            .emit();
2132    }
2133
2134    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
2135        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2136    }
2137
2138    #[instrument(level = "debug", skip(self), ret)]
2139    fn lower_param_bounds(
2140        &mut self,
2141        bounds: &[GenericBound],
2142        rbp: RelaxedBoundPolicy<'_>,
2143        itctx: ImplTraitContext,
2144    ) -> hir::GenericBounds<'hir> {
2145        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
2146    }
2147
2148    fn lower_param_bounds_mut(
2149        &mut self,
2150        bounds: &[GenericBound],
2151        rbp: RelaxedBoundPolicy<'_>,
2152        itctx: ImplTraitContext,
2153    ) -> impl Iterator<Item = hir::GenericBound<'hir>> {
2154        bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
2155    }
2156
2157    #[instrument(level = "debug", skip(self), ret)]
2158    fn lower_universal_param_and_bounds(
2159        &mut self,
2160        node_id: NodeId,
2161        span: Span,
2162        ident: Ident,
2163        bounds: &[GenericBound],
2164    ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2165        // Add a definition for the in-band `Param`.
2166        let def_id = self.local_def_id(node_id);
2167        let span = self.lower_span(span);
2168
2169        // Set the name to `impl Bound1 + Bound2`.
2170        let param = hir::GenericParam {
2171            hir_id: self.lower_node_id(node_id),
2172            def_id,
2173            name: ParamName::Plain(self.lower_ident(ident)),
2174            pure_wrt_drop: false,
2175            span,
2176            kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2177            colon_span: None,
2178            source: hir::GenericParamSource::Generics,
2179        };
2180
2181        let preds = self.lower_generic_bound_predicate(
2182            ident,
2183            node_id,
2184            &GenericParamKind::Type { default: None },
2185            bounds,
2186            /* colon_span */ None,
2187            span,
2188            RelaxedBoundPolicy::Allowed,
2189            ImplTraitContext::Universal,
2190            hir::PredicateOrigin::ImplTrait,
2191        );
2192
2193        let hir_id = self.next_id();
2194        let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
2195        let ty = hir::TyKind::Path(hir::QPath::Resolved(
2196            None,
2197            self.arena.alloc(hir::Path {
2198                span,
2199                res,
2200                segments:
2201                    arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
2202            }),
2203        ));
2204
2205        (param, preds, ty)
2206    }
2207
2208    /// Lowers a block directly to an expression, presuming that it
2209    /// has no attributes and is not targeted by a `break`.
2210    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2211        let block = self.lower_block(b, false);
2212        self.expr_block(block)
2213    }
2214
2215    fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2216        // We cannot just match on `ExprKind::Underscore` as `(_)` is represented as
2217        // `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
2218        match c.value.peel_parens().kind {
2219            ExprKind::Underscore => {
2220                let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
2221                self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
2222            }
2223            _ => self.lower_anon_const_to_const_arg(c),
2224        }
2225    }
2226
2227    /// Used when lowering a type argument that turned out to actually be a const argument.
2228    ///
2229    /// Only use for that purpose since otherwise it will create a duplicate def.
2230    #[instrument(level = "debug", skip(self))]
2231    fn lower_const_path_to_const_arg(
2232        &mut self,
2233        path: &Path,
2234        res: Res<NodeId>,
2235        ty_id: NodeId,
2236        span: Span,
2237    ) -> &'hir hir::ConstArg<'hir> {
2238        let tcx = self.tcx;
2239
2240        let ct_kind = if path
2241            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2242            && (tcx.features().min_generic_const_args()
2243                || matches!(res, Res::Def(DefKind::ConstParam, _)))
2244        {
2245            let qpath = self.lower_qpath(
2246                ty_id,
2247                &None,
2248                path,
2249                ParamMode::Explicit,
2250                AllowReturnTypeNotation::No,
2251                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2252                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2253                None,
2254            );
2255            hir::ConstArgKind::Path(qpath)
2256        } else {
2257            // Construct an AnonConst where the expr is the "ty"'s path.
2258            let node_id = self.next_node_id();
2259            let span = self.lower_span(span);
2260
2261            // Add a definition for the in-band const def.
2262            // We're lowering a const argument that was originally thought to be a type argument,
2263            // so the def collector didn't create the def ahead of time. That's why we have to do
2264            // it here.
2265            let def_id = self.create_def(node_id, None, DefKind::AnonConst, span);
2266            let hir_id = self.lower_node_id(node_id);
2267
2268            let path_expr = Expr {
2269                id: ty_id,
2270                kind: ExprKind::Path(None, path.clone()),
2271                span,
2272                attrs: AttrVec::new(),
2273                tokens: None,
2274            };
2275
2276            let ct = self.with_new_scopes(span, |this| {
2277                self.arena.alloc(hir::AnonConst {
2278                    def_id,
2279                    hir_id,
2280                    body: this.lower_const_body(path_expr.span, Some(&path_expr)),
2281                    span,
2282                })
2283            });
2284            hir::ConstArgKind::Anon(ct)
2285        };
2286
2287        self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
2288    }
2289
2290    /// See [`hir::ConstArg`] for when to use this function vs
2291    /// [`Self::lower_anon_const_to_anon_const`].
2292    fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> &'hir hir::ConstArg<'hir> {
2293        self.arena.alloc(self.lower_anon_const_to_const_arg_direct(anon))
2294    }
2295
2296    #[instrument(level = "debug", skip(self))]
2297    fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2298        let tcx = self.tcx;
2299        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
2300        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
2301        let expr = if let ExprKind::Block(block, _) = &anon.value.kind
2302            && let [stmt] = block.stmts.as_slice()
2303            && let StmtKind::Expr(expr) = &stmt.kind
2304            && let ExprKind::Path(..) = &expr.kind
2305        {
2306            expr
2307        } else {
2308            &anon.value
2309        };
2310        let maybe_res =
2311            self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2312        if let ExprKind::Path(qself, path) = &expr.kind
2313            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
2314            && (tcx.features().min_generic_const_args()
2315                || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
2316        {
2317            let qpath = self.lower_qpath(
2318                expr.id,
2319                qself,
2320                path,
2321                ParamMode::Explicit,
2322                AllowReturnTypeNotation::No,
2323                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
2324                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2325                None,
2326            );
2327
2328            return ConstArg {
2329                hir_id: self.lower_node_id(anon.id),
2330                kind: hir::ConstArgKind::Path(qpath),
2331            };
2332        }
2333
2334        let lowered_anon = self.lower_anon_const_to_anon_const(anon);
2335        ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
2336    }
2337
2338    /// See [`hir::ConstArg`] for when to use this function vs
2339    /// [`Self::lower_anon_const_to_const_arg`].
2340    fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
2341        self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
2342            let def_id = this.local_def_id(c.id);
2343            let hir_id = this.lower_node_id(c.id);
2344            hir::AnonConst {
2345                def_id,
2346                hir_id,
2347                body: this.lower_const_body(c.value.span, Some(&c.value)),
2348                span: this.lower_span(c.value.span),
2349            }
2350        }))
2351    }
2352
2353    fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2354        match u {
2355            CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2356            UserProvided => hir::UnsafeSource::UserProvided,
2357        }
2358    }
2359
2360    fn lower_trait_bound_modifiers(
2361        &mut self,
2362        modifiers: TraitBoundModifiers,
2363    ) -> hir::TraitBoundModifiers {
2364        hir::TraitBoundModifiers { constness: modifiers.constness, polarity: modifiers.polarity }
2365    }
2366
2367    // Helper methods for building HIR.
2368
2369    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2370        hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2371    }
2372
2373    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2374        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2375    }
2376
2377    fn stmt_let_pat(
2378        &mut self,
2379        attrs: Option<&'hir [hir::Attribute]>,
2380        span: Span,
2381        init: Option<&'hir hir::Expr<'hir>>,
2382        pat: &'hir hir::Pat<'hir>,
2383        source: hir::LocalSource,
2384    ) -> hir::Stmt<'hir> {
2385        let hir_id = self.next_id();
2386        if let Some(a) = attrs {
2387            assert!(!a.is_empty());
2388            self.attrs.insert(hir_id.local_id, a);
2389        }
2390        let local = hir::LetStmt {
2391            super_: None,
2392            hir_id,
2393            init,
2394            pat,
2395            els: None,
2396            source,
2397            span: self.lower_span(span),
2398            ty: None,
2399        };
2400        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2401    }
2402
2403    fn stmt_super_let_pat(
2404        &mut self,
2405        span: Span,
2406        pat: &'hir hir::Pat<'hir>,
2407        init: Option<&'hir hir::Expr<'hir>>,
2408    ) -> hir::Stmt<'hir> {
2409        let hir_id = self.next_id();
2410        let local = hir::LetStmt {
2411            super_: Some(span),
2412            hir_id,
2413            init,
2414            pat,
2415            els: None,
2416            source: hir::LocalSource::Normal,
2417            span: self.lower_span(span),
2418            ty: None,
2419        };
2420        self.stmt(span, hir::StmtKind::Let(self.arena.alloc(local)))
2421    }
2422
2423    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2424        self.block_all(expr.span, &[], Some(expr))
2425    }
2426
2427    fn block_all(
2428        &mut self,
2429        span: Span,
2430        stmts: &'hir [hir::Stmt<'hir>],
2431        expr: Option<&'hir hir::Expr<'hir>>,
2432    ) -> &'hir hir::Block<'hir> {
2433        let blk = hir::Block {
2434            stmts,
2435            expr,
2436            hir_id: self.next_id(),
2437            rules: hir::BlockCheckMode::DefaultBlock,
2438            span: self.lower_span(span),
2439            targeted_by_break: false,
2440        };
2441        self.arena.alloc(blk)
2442    }
2443
2444    fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2445        let field = self.single_pat_field(span, pat);
2446        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2447    }
2448
2449    fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2450        let field = self.single_pat_field(span, pat);
2451        self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2452    }
2453
2454    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2455        let field = self.single_pat_field(span, pat);
2456        self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2457    }
2458
2459    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2460        self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2461    }
2462
2463    fn single_pat_field(
2464        &mut self,
2465        span: Span,
2466        pat: &'hir hir::Pat<'hir>,
2467    ) -> &'hir [hir::PatField<'hir>] {
2468        let field = hir::PatField {
2469            hir_id: self.next_id(),
2470            ident: Ident::new(sym::integer(0), self.lower_span(span)),
2471            is_shorthand: false,
2472            pat,
2473            span: self.lower_span(span),
2474        };
2475        arena_vec![self; field]
2476    }
2477
2478    fn pat_lang_item_variant(
2479        &mut self,
2480        span: Span,
2481        lang_item: hir::LangItem,
2482        fields: &'hir [hir::PatField<'hir>],
2483    ) -> &'hir hir::Pat<'hir> {
2484        let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2485        self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2486    }
2487
2488    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) {
2489        self.pat_ident_binding_mode(span, ident, hir::BindingMode::NONE)
2490    }
2491
2492    fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) {
2493        self.pat_ident_binding_mode_mut(span, ident, hir::BindingMode::NONE)
2494    }
2495
2496    fn pat_ident_binding_mode(
2497        &mut self,
2498        span: Span,
2499        ident: Ident,
2500        bm: hir::BindingMode,
2501    ) -> (&'hir hir::Pat<'hir>, HirId) {
2502        let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2503        (self.arena.alloc(pat), hir_id)
2504    }
2505
2506    fn pat_ident_binding_mode_mut(
2507        &mut self,
2508        span: Span,
2509        ident: Ident,
2510        bm: hir::BindingMode,
2511    ) -> (hir::Pat<'hir>, HirId) {
2512        let hir_id = self.next_id();
2513
2514        (
2515            hir::Pat {
2516                hir_id,
2517                kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2518                span: self.lower_span(span),
2519                default_binding_modes: true,
2520            },
2521            hir_id,
2522        )
2523    }
2524
2525    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2526        self.arena.alloc(hir::Pat {
2527            hir_id: self.next_id(),
2528            kind,
2529            span: self.lower_span(span),
2530            default_binding_modes: true,
2531        })
2532    }
2533
2534    fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2535        hir::Pat {
2536            hir_id: self.next_id(),
2537            kind,
2538            span: self.lower_span(span),
2539            default_binding_modes: false,
2540        }
2541    }
2542
2543    fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> {
2544        let kind = match qpath {
2545            hir::QPath::Resolved(None, path) => {
2546                // Turn trait object paths into `TyKind::TraitObject` instead.
2547                match path.res {
2548                    Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2549                        let principal = hir::PolyTraitRef {
2550                            bound_generic_params: &[],
2551                            modifiers: hir::TraitBoundModifiers::NONE,
2552                            trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2553                            span: self.lower_span(span),
2554                        };
2555
2556                        // The original ID is taken by the `PolyTraitRef`,
2557                        // so the `Ty` itself needs a different one.
2558                        hir_id = self.next_id();
2559                        hir::TyKind::TraitObject(
2560                            arena_vec![self; principal],
2561                            TaggedRef::new(self.elided_dyn_bound(span), TraitObjectSyntax::None),
2562                        )
2563                    }
2564                    _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2565                }
2566            }
2567            _ => hir::TyKind::Path(qpath),
2568        };
2569
2570        hir::Ty { hir_id, kind, span: self.lower_span(span) }
2571    }
2572
2573    /// Invoked to create the lifetime argument(s) for an elided trait object
2574    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2575    /// when the bound is written, even if it is written with `'_` like in
2576    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2577    fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
2578        let r = hir::Lifetime::new(
2579            self.next_id(),
2580            Ident::new(kw::UnderscoreLifetime, self.lower_span(span)),
2581            hir::LifetimeKind::ImplicitObjectLifetimeDefault,
2582            LifetimeSource::Other,
2583            LifetimeSyntax::Implicit,
2584        );
2585        debug!("elided_dyn_bound: r={:?}", r);
2586        self.arena.alloc(r)
2587    }
2588}
2589
2590/// Helper struct for the delayed construction of [`hir::GenericArgs`].
2591struct GenericArgsCtor<'hir> {
2592    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2593    constraints: &'hir [hir::AssocItemConstraint<'hir>],
2594    parenthesized: hir::GenericArgsParentheses,
2595    span: Span,
2596}
2597
2598impl<'hir> GenericArgsCtor<'hir> {
2599    fn is_empty(&self) -> bool {
2600        self.args.is_empty()
2601            && self.constraints.is_empty()
2602            && self.parenthesized == hir::GenericArgsParentheses::No
2603    }
2604
2605    fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2606        let ga = hir::GenericArgs {
2607            args: this.arena.alloc_from_iter(self.args),
2608            constraints: self.constraints,
2609            parenthesized: self.parenthesized,
2610            span_ext: this.lower_span(self.span),
2611        };
2612        this.arena.alloc(ga)
2613    }
2614}