rustc_ast_lowering/
lib.rs

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