rustc_ast_lowering/
lib.rs

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