rustc_ast_lowering/
lib.rs

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