rustc_ast_lowering/
item.rs

1use rustc_abi::ExternAbi;
2use rustc_ast::ptr::P;
3use rustc_ast::visit::AssocCtxt;
4use rustc_ast::*;
5use rustc_errors::ErrorGuaranteed;
6use rustc_hir::def::{DefKind, PerNS, Res};
7use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
8use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin};
9use rustc_index::{IndexSlice, IndexVec};
10use rustc_middle::span_bug;
11use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
12use rustc_span::edit_distance::find_best_match_for_name;
13use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
14use smallvec::{SmallVec, smallvec};
15use thin_vec::ThinVec;
16use tracing::instrument;
17
18use super::errors::{
19    InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound, TupleStructWithDefault,
20};
21use super::stability::{enabled_names, gate_unstable_abi};
22use super::{
23    AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
24    ResolverAstLoweringExt,
25};
26
27pub(super) struct ItemLowerer<'a, 'hir> {
28    pub(super) tcx: TyCtxt<'hir>,
29    pub(super) resolver: &'a mut ResolverAstLowering,
30    pub(super) ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,
31    pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<'hir>>,
32}
33
34/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
35/// to the where clause that is preferred, if it exists. Otherwise, it sets the span to the other where
36/// clause if it exists.
37fn add_ty_alias_where_clause(
38    generics: &mut ast::Generics,
39    mut where_clauses: TyAliasWhereClauses,
40    prefer_first: bool,
41) {
42    if !prefer_first {
43        (where_clauses.before, where_clauses.after) = (where_clauses.after, where_clauses.before);
44    }
45    let where_clause =
46        if where_clauses.before.has_where_token || !where_clauses.after.has_where_token {
47            where_clauses.before
48        } else {
49            where_clauses.after
50        };
51    generics.where_clause.has_where_token = where_clause.has_where_token;
52    generics.where_clause.span = where_clause.span;
53}
54
55impl<'a, 'hir> ItemLowerer<'a, 'hir> {
56    fn with_lctx(
57        &mut self,
58        owner: NodeId,
59        f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
60    ) {
61        let mut lctx = LoweringContext::new(self.tcx, self.resolver);
62        lctx.with_hir_id_owner(owner, |lctx| f(lctx));
63
64        for (def_id, info) in lctx.children {
65            let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
66            assert!(
67                matches!(owner, hir::MaybeOwner::Phantom),
68                "duplicate copy of {def_id:?} in lctx.children"
69            );
70            *owner = info;
71        }
72    }
73
74    pub(super) fn lower_node(&mut self, def_id: LocalDefId) {
75        let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
76        if let hir::MaybeOwner::Phantom = owner {
77            let node = self.ast_index[def_id];
78            match node {
79                AstOwner::NonOwner => {}
80                AstOwner::Crate(c) => {
81                    assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
82                    self.with_lctx(CRATE_NODE_ID, |lctx| {
83                        let module = lctx.lower_mod(&c.items, &c.spans);
84                        // FIXME(jdonszelman): is dummy span ever a problem here?
85                        lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
86                        hir::OwnerNode::Crate(module)
87                    })
88                }
89                AstOwner::Item(item) => {
90                    self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
91                }
92                AstOwner::AssocItem(item, ctxt) => {
93                    self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
94                }
95                AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
96                    hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
97                }),
98            }
99        }
100    }
101}
102
103impl<'hir> LoweringContext<'_, 'hir> {
104    pub(super) fn lower_mod(
105        &mut self,
106        items: &[P<Item>],
107        spans: &ModSpans,
108    ) -> &'hir hir::Mod<'hir> {
109        self.arena.alloc(hir::Mod {
110            spans: hir::ModSpans {
111                inner_span: self.lower_span(spans.inner_span),
112                inject_use_span: self.lower_span(spans.inject_use_span),
113            },
114            item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
115        })
116    }
117
118    pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
119        let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }];
120        if let ItemKind::Use(use_tree) = &i.kind {
121            self.lower_item_id_use_tree(use_tree, &mut node_ids);
122        }
123        node_ids
124    }
125
126    fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
127        match &tree.kind {
128            UseTreeKind::Nested { items, .. } => {
129                for &(ref nested, id) in items {
130                    vec.push(hir::ItemId { owner_id: self.owner_id(id) });
131                    self.lower_item_id_use_tree(nested, vec);
132                }
133            }
134            UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
135        }
136    }
137
138    fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
139        let vis_span = self.lower_span(i.vis.span);
140        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
141        let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
142        let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
143        let item = hir::Item {
144            owner_id: hir_id.expect_owner(),
145            kind,
146            vis_span,
147            span: self.lower_span(i.span),
148        };
149        self.arena.alloc(item)
150    }
151
152    fn lower_item_kind(
153        &mut self,
154        span: Span,
155        id: NodeId,
156        hir_id: hir::HirId,
157        attrs: &'hir [hir::Attribute],
158        vis_span: Span,
159        i: &ItemKind,
160    ) -> hir::ItemKind<'hir> {
161        match i {
162            ItemKind::ExternCrate(orig_name, ident) => {
163                let ident = self.lower_ident(*ident);
164                hir::ItemKind::ExternCrate(*orig_name, ident)
165            }
166            ItemKind::Use(use_tree) => {
167                // Start with an empty prefix.
168                let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
169
170                self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
171            }
172            ItemKind::Static(box ast::StaticItem {
173                ident,
174                ty: t,
175                safety: _,
176                mutability: m,
177                expr: e,
178                define_opaque,
179            }) => {
180                let ident = self.lower_ident(*ident);
181                let (ty, body_id) =
182                    self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
183                self.lower_define_opaque(hir_id, define_opaque);
184                hir::ItemKind::Static(*m, ident, ty, body_id)
185            }
186            ItemKind::Const(box ast::ConstItem {
187                ident,
188                generics,
189                ty,
190                expr,
191                define_opaque,
192                ..
193            }) => {
194                let ident = self.lower_ident(*ident);
195                let (generics, (ty, body_id)) = self.lower_generics(
196                    generics,
197                    id,
198                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
199                    |this| {
200                        this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
201                    },
202                );
203                self.lower_define_opaque(hir_id, &define_opaque);
204                hir::ItemKind::Const(ident, generics, ty, body_id)
205            }
206            ItemKind::Fn(box Fn {
207                sig: FnSig { decl, header, span: fn_sig_span },
208                ident,
209                generics,
210                body,
211                contract,
212                define_opaque,
213                ..
214            }) => {
215                self.with_new_scopes(*fn_sig_span, |this| {
216                    // Note: we don't need to change the return type from `T` to
217                    // `impl Future<Output = T>` here because lower_body
218                    // only cares about the input argument patterns in the function
219                    // declaration (decl), not the return types.
220                    let coroutine_kind = header.coroutine_kind;
221                    let body_id = this.lower_maybe_coroutine_body(
222                        *fn_sig_span,
223                        span,
224                        hir_id,
225                        decl,
226                        coroutine_kind,
227                        body.as_deref(),
228                        attrs,
229                        contract.as_deref(),
230                    );
231
232                    let itctx = ImplTraitContext::Universal;
233                    let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
234                        this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coroutine_kind)
235                    });
236                    let sig = hir::FnSig {
237                        decl,
238                        header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
239                        span: this.lower_span(*fn_sig_span),
240                    };
241                    this.lower_define_opaque(hir_id, define_opaque);
242                    let ident = this.lower_ident(*ident);
243                    hir::ItemKind::Fn {
244                        ident,
245                        sig,
246                        generics,
247                        body: body_id,
248                        has_body: body.is_some(),
249                    }
250                })
251            }
252            ItemKind::Mod(_, ident, mod_kind) => {
253                let ident = self.lower_ident(*ident);
254                match mod_kind {
255                    ModKind::Loaded(items, _, spans, _) => {
256                        hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
257                    }
258                    ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
259                }
260            }
261            ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
262                abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
263                items: self
264                    .arena
265                    .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
266            },
267            ItemKind::GlobalAsm(asm) => {
268                let asm = self.lower_inline_asm(span, asm);
269                let fake_body =
270                    self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
271                hir::ItemKind::GlobalAsm { asm, fake_body }
272            }
273            ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
274                // We lower
275                //
276                // type Foo = impl Trait
277                //
278                // to
279                //
280                // type Foo = Foo1
281                // opaque type Foo1: Trait
282                let ident = self.lower_ident(*ident);
283                let mut generics = generics.clone();
284                add_ty_alias_where_clause(&mut generics, *where_clauses, true);
285                let (generics, ty) = self.lower_generics(
286                    &generics,
287                    id,
288                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
289                    |this| match ty {
290                        None => {
291                            let guar = this.dcx().span_delayed_bug(
292                                span,
293                                "expected to lower type alias type, but it was missing",
294                            );
295                            this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
296                        }
297                        Some(ty) => this.lower_ty(
298                            ty,
299                            ImplTraitContext::OpaqueTy {
300                                origin: hir::OpaqueTyOrigin::TyAlias {
301                                    parent: this.local_def_id(id),
302                                    in_assoc_ty: false,
303                                },
304                            },
305                        ),
306                    },
307                );
308                hir::ItemKind::TyAlias(ident, generics, ty)
309            }
310            ItemKind::Enum(ident, generics, enum_definition) => {
311                let ident = self.lower_ident(*ident);
312                let (generics, variants) = self.lower_generics(
313                    generics,
314                    id,
315                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
316                    |this| {
317                        this.arena.alloc_from_iter(
318                            enum_definition.variants.iter().map(|x| this.lower_variant(x)),
319                        )
320                    },
321                );
322                hir::ItemKind::Enum(ident, generics, hir::EnumDef { variants })
323            }
324            ItemKind::Struct(ident, generics, struct_def) => {
325                let ident = self.lower_ident(*ident);
326                let (generics, struct_def) = self.lower_generics(
327                    generics,
328                    id,
329                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
330                    |this| this.lower_variant_data(hir_id, struct_def),
331                );
332                hir::ItemKind::Struct(ident, generics, struct_def)
333            }
334            ItemKind::Union(ident, generics, vdata) => {
335                let ident = self.lower_ident(*ident);
336                let (generics, vdata) = self.lower_generics(
337                    generics,
338                    id,
339                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
340                    |this| this.lower_variant_data(hir_id, vdata),
341                );
342                hir::ItemKind::Union(ident, generics, vdata)
343            }
344            ItemKind::Impl(box Impl {
345                safety,
346                polarity,
347                defaultness,
348                constness,
349                generics: ast_generics,
350                of_trait: trait_ref,
351                self_ty: ty,
352                items: impl_items,
353            }) => {
354                // Lower the "impl header" first. This ordering is important
355                // for in-band lifetimes! Consider `'a` here:
356                //
357                //     impl Foo<'a> for u32 {
358                //         fn method(&'a self) { .. }
359                //     }
360                //
361                // Because we start by lowering the `Foo<'a> for u32`
362                // part, we will add `'a` to the list of generics on
363                // the impl. When we then encounter it later in the
364                // method, it will not be considered an in-band
365                // lifetime to be added, but rather a reference to a
366                // parent lifetime.
367                let itctx = ImplTraitContext::Universal;
368                let (generics, (trait_ref, lowered_ty)) =
369                    self.lower_generics(ast_generics, id, itctx, |this| {
370                        let modifiers = TraitBoundModifiers {
371                            constness: BoundConstness::Never,
372                            asyncness: BoundAsyncness::Normal,
373                            // we don't use this in bound lowering
374                            polarity: BoundPolarity::Positive,
375                        };
376
377                        let trait_ref = trait_ref.as_ref().map(|trait_ref| {
378                            this.lower_trait_ref(
379                                modifiers,
380                                trait_ref,
381                                ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
382                            )
383                        });
384
385                        let lowered_ty = this.lower_ty(
386                            ty,
387                            ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
388                        );
389
390                        (trait_ref, lowered_ty)
391                    });
392
393                let new_impl_items = self.arena.alloc_from_iter(
394                    impl_items
395                        .iter()
396                        .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
397                );
398
399                // `defaultness.has_value()` is never called for an `impl`, always `true` in order
400                // to not cause an assertion failure inside the `lower_defaultness` function.
401                let has_val = true;
402                let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val);
403                let polarity = match polarity {
404                    ImplPolarity::Positive => ImplPolarity::Positive,
405                    ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
406                };
407                hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
408                    constness: self.lower_constness(*constness),
409                    safety: self.lower_safety(*safety, hir::Safety::Safe),
410                    polarity,
411                    defaultness,
412                    defaultness_span,
413                    generics,
414                    of_trait: trait_ref,
415                    self_ty: lowered_ty,
416                    items: new_impl_items,
417                }))
418            }
419            ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
420                let ident = self.lower_ident(*ident);
421                let (generics, (safety, items, bounds)) = self.lower_generics(
422                    generics,
423                    id,
424                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
425                    |this| {
426                        let bounds = this.lower_param_bounds(
427                            bounds,
428                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
429                        );
430                        let items = this.arena.alloc_from_iter(
431                            items.iter().map(|item| this.lower_trait_item_ref(item)),
432                        );
433                        let safety = this.lower_safety(*safety, hir::Safety::Safe);
434                        (safety, items, bounds)
435                    },
436                );
437                hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
438            }
439            ItemKind::TraitAlias(ident, generics, bounds) => {
440                let ident = self.lower_ident(*ident);
441                let (generics, bounds) = self.lower_generics(
442                    generics,
443                    id,
444                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
445                    |this| {
446                        this.lower_param_bounds(
447                            bounds,
448                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
449                        )
450                    },
451                );
452                hir::ItemKind::TraitAlias(ident, generics, bounds)
453            }
454            ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
455                let ident = self.lower_ident(*ident);
456                let body = P(self.lower_delim_args(body));
457                let def_id = self.local_def_id(id);
458                let def_kind = self.tcx.def_kind(def_id);
459                let DefKind::Macro(macro_kind) = def_kind else {
460                    unreachable!(
461                        "expected DefKind::Macro for macro item, found {}",
462                        def_kind.descr(def_id.to_def_id())
463                    );
464                };
465                let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
466                hir::ItemKind::Macro(ident, macro_def, macro_kind)
467            }
468            ItemKind::Delegation(box delegation) => {
469                let delegation_results = self.lower_delegation(delegation, id, false);
470                hir::ItemKind::Fn {
471                    sig: delegation_results.sig,
472                    ident: delegation_results.ident,
473                    generics: delegation_results.generics,
474                    body: delegation_results.body_id,
475                    has_body: true,
476                }
477            }
478            ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
479                panic!("macros should have been expanded by now")
480            }
481        }
482    }
483
484    fn lower_const_item(
485        &mut self,
486        ty: &Ty,
487        span: Span,
488        body: Option<&Expr>,
489        impl_trait_position: ImplTraitPosition,
490    ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
491        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
492        (ty, self.lower_const_body(span, body))
493    }
494
495    #[instrument(level = "debug", skip(self))]
496    fn lower_use_tree(
497        &mut self,
498        tree: &UseTree,
499        prefix: &Path,
500        id: NodeId,
501        vis_span: Span,
502        attrs: &'hir [hir::Attribute],
503    ) -> hir::ItemKind<'hir> {
504        let path = &tree.prefix;
505        let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
506
507        match tree.kind {
508            UseTreeKind::Simple(rename) => {
509                let mut ident = tree.ident();
510
511                // First, apply the prefix to the path.
512                let mut path = Path { segments, span: path.span, tokens: None };
513
514                // Correctly resolve `self` imports.
515                if path.segments.len() > 1
516                    && path.segments.last().unwrap().ident.name == kw::SelfLower
517                {
518                    let _ = path.segments.pop();
519                    if rename.is_none() {
520                        ident = path.segments.last().unwrap().ident;
521                    }
522                }
523
524                let res = self.lower_import_res(id, path.span);
525                let path = self.lower_use_path(res, &path, ParamMode::Explicit);
526                let ident = self.lower_ident(ident);
527                hir::ItemKind::Use(path, hir::UseKind::Single(ident))
528            }
529            UseTreeKind::Glob => {
530                let res = self.expect_full_res(id);
531                let res = self.lower_res(res);
532                // Put the result in the appropriate namespace.
533                let res = match res {
534                    Res::Def(DefKind::Mod | DefKind::Trait, _) => {
535                        PerNS { type_ns: Some(res), value_ns: None, macro_ns: None }
536                    }
537                    Res::Def(DefKind::Enum, _) => {
538                        PerNS { type_ns: None, value_ns: Some(res), macro_ns: None }
539                    }
540                    Res::Err => {
541                        // Propagate the error to all namespaces, just to be sure.
542                        let err = Some(Res::Err);
543                        PerNS { type_ns: err, value_ns: err, macro_ns: err }
544                    }
545                    _ => span_bug!(path.span, "bad glob res {:?}", res),
546                };
547                let path = Path { segments, span: path.span, tokens: None };
548                let path = self.lower_use_path(res, &path, ParamMode::Explicit);
549                hir::ItemKind::Use(path, hir::UseKind::Glob)
550            }
551            UseTreeKind::Nested { items: ref trees, .. } => {
552                // Nested imports are desugared into simple imports.
553                // So, if we start with
554                //
555                // ```
556                // pub(x) use foo::{a, b};
557                // ```
558                //
559                // we will create three items:
560                //
561                // ```
562                // pub(x) use foo::a;
563                // pub(x) use foo::b;
564                // pub(x) use foo::{}; // <-- this is called the `ListStem`
565                // ```
566                //
567                // The first two are produced by recursively invoking
568                // `lower_use_tree` (and indeed there may be things
569                // like `use foo::{a::{b, c}}` and so forth). They
570                // wind up being directly added to
571                // `self.items`. However, the structure of this
572                // function also requires us to return one item, and
573                // for that we return the `{}` import (called the
574                // `ListStem`).
575
576                let span = prefix.span.to(path.span);
577                let prefix = Path { segments, span, tokens: None };
578
579                // Add all the nested `PathListItem`s to the HIR.
580                for &(ref use_tree, id) in trees {
581                    let owner_id = self.owner_id(id);
582
583                    // Each `use` import is an item and thus are owners of the
584                    // names in the path. Up to this point the nested import is
585                    // the current owner, since we want each desugared import to
586                    // own its own names, we have to adjust the owner before
587                    // lowering the rest of the import.
588                    self.with_hir_id_owner(id, |this| {
589                        // `prefix` is lowered multiple times, but in different HIR owners.
590                        // So each segment gets renewed `HirId` with the same
591                        // `ItemLocalId` and the new owner. (See `lower_node_id`)
592                        let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
593                        if !attrs.is_empty() {
594                            this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
595                        }
596
597                        let item = hir::Item {
598                            owner_id,
599                            kind,
600                            vis_span,
601                            span: this.lower_span(use_tree.span),
602                        };
603                        hir::OwnerNode::Item(this.arena.alloc(item))
604                    });
605                }
606
607                // Condition should match `build_reduced_graph_for_use_tree`.
608                let path = if trees.is_empty()
609                    && !(prefix.segments.is_empty()
610                        || prefix.segments.len() == 1
611                            && prefix.segments[0].ident.name == kw::PathRoot)
612                {
613                    // For empty lists we need to lower the prefix so it is checked for things
614                    // like stability later.
615                    let res = self.lower_import_res(id, span);
616                    self.lower_use_path(res, &prefix, ParamMode::Explicit)
617                } else {
618                    // For non-empty lists we can just drop all the data, the prefix is already
619                    // present in HIR as a part of nested imports.
620                    self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span })
621                };
622                hir::ItemKind::Use(path, hir::UseKind::ListStem)
623            }
624        }
625    }
626
627    fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
628        // Evaluate with the lifetimes in `params` in-scope.
629        // This is used to track which lifetimes have already been defined,
630        // and which need to be replicated when lowering an async fn.
631        match ctxt {
632            AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
633            AssocCtxt::Impl { of_trait } => {
634                hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
635            }
636        }
637    }
638
639    fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
640        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
641        let owner_id = hir_id.expect_owner();
642        let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
643        let (ident, kind) = match &i.kind {
644            ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
645                let fdec = &sig.decl;
646                let itctx = ImplTraitContext::Universal;
647                let (generics, (decl, fn_args)) =
648                    self.lower_generics(generics, i.id, itctx, |this| {
649                        (
650                            // Disallow `impl Trait` in foreign items.
651                            this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
652                            this.lower_fn_params_to_idents(fdec),
653                        )
654                    });
655
656                // Unmarked safety in unsafe block defaults to unsafe.
657                let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
658
659                if define_opaque.is_some() {
660                    self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
661                }
662
663                (
664                    ident,
665                    hir::ForeignItemKind::Fn(
666                        hir::FnSig { header, decl, span: self.lower_span(sig.span) },
667                        fn_args,
668                        generics,
669                    ),
670                )
671            }
672            ForeignItemKind::Static(box StaticItem {
673                ident,
674                ty,
675                mutability,
676                expr: _,
677                safety,
678                define_opaque,
679            }) => {
680                let ty =
681                    self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
682                let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
683                if define_opaque.is_some() {
684                    self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
685                }
686                (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
687            }
688            ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
689                (ident, hir::ForeignItemKind::Type)
690            }
691            ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
692        };
693
694        let item = hir::ForeignItem {
695            owner_id,
696            ident: self.lower_ident(*ident),
697            kind,
698            vis_span: self.lower_span(i.vis.span),
699            span: self.lower_span(i.span),
700        };
701        self.arena.alloc(item)
702    }
703
704    fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
705        hir::ForeignItemRef {
706            id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
707            // `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
708            // without an identifier and it cannot reach here.
709            ident: self.lower_ident(i.kind.ident().unwrap()),
710            span: self.lower_span(i.span),
711        }
712    }
713
714    fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
715        let hir_id = self.lower_node_id(v.id);
716        self.lower_attrs(hir_id, &v.attrs, v.span);
717        hir::Variant {
718            hir_id,
719            def_id: self.local_def_id(v.id),
720            data: self.lower_variant_data(hir_id, &v.data),
721            disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
722            ident: self.lower_ident(v.ident),
723            span: self.lower_span(v.span),
724        }
725    }
726
727    fn lower_variant_data(
728        &mut self,
729        parent_id: hir::HirId,
730        vdata: &VariantData,
731    ) -> hir::VariantData<'hir> {
732        match vdata {
733            VariantData::Struct { fields, recovered } => hir::VariantData::Struct {
734                fields: self
735                    .arena
736                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
737                recovered: *recovered,
738            },
739            VariantData::Tuple(fields, id) => {
740                let ctor_id = self.lower_node_id(*id);
741                self.alias_attrs(ctor_id, parent_id);
742                let fields = self
743                    .arena
744                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
745                for field in &fields[..] {
746                    if let Some(default) = field.default {
747                        // Default values in tuple struct and tuple variants are not allowed by the
748                        // RFC due to concerns about the syntax, both in the item definition and the
749                        // expression. We could in the future allow `struct S(i32 = 0);` and force
750                        // users to construct the value with `let _ = S { .. };`.
751                        if self.tcx.features().default_field_values() {
752                            self.dcx().emit_err(TupleStructWithDefault { span: default.span });
753                        } else {
754                            let _ = self.dcx().span_delayed_bug(
755                                default.span,
756                                "expected `default values on `struct` fields aren't supported` \
757                                 feature-gate error but none was produced",
758                            );
759                        }
760                    }
761                }
762                hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))
763            }
764            VariantData::Unit(id) => {
765                let ctor_id = self.lower_node_id(*id);
766                self.alias_attrs(ctor_id, parent_id);
767                hir::VariantData::Unit(ctor_id, self.local_def_id(*id))
768            }
769        }
770    }
771
772    pub(super) fn lower_field_def(
773        &mut self,
774        (index, f): (usize, &FieldDef),
775    ) -> hir::FieldDef<'hir> {
776        let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
777        let hir_id = self.lower_node_id(f.id);
778        self.lower_attrs(hir_id, &f.attrs, f.span);
779        hir::FieldDef {
780            span: self.lower_span(f.span),
781            hir_id,
782            def_id: self.local_def_id(f.id),
783            ident: match f.ident {
784                Some(ident) => self.lower_ident(ident),
785                // FIXME(jseyfried): positional field hygiene.
786                None => Ident::new(sym::integer(index), self.lower_span(f.span)),
787            },
788            vis_span: self.lower_span(f.vis.span),
789            default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
790            ty,
791            safety: self.lower_safety(f.safety, hir::Safety::Safe),
792        }
793    }
794
795    fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
796        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
797        let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
798        let trait_item_def_id = hir_id.expect_owner();
799
800        let (ident, generics, kind, has_default) = match &i.kind {
801            AssocItemKind::Const(box ConstItem {
802                ident,
803                generics,
804                ty,
805                expr,
806                define_opaque,
807                ..
808            }) => {
809                let (generics, kind) = self.lower_generics(
810                    generics,
811                    i.id,
812                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
813                    |this| {
814                        let ty = this
815                            .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
816                        let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
817
818                        hir::TraitItemKind::Const(ty, body)
819                    },
820                );
821
822                if define_opaque.is_some() {
823                    if expr.is_some() {
824                        self.lower_define_opaque(hir_id, &define_opaque);
825                    } else {
826                        self.dcx().span_err(
827                            i.span,
828                            "only trait consts with default bodies can define opaque types",
829                        );
830                    }
831                }
832
833                (*ident, generics, kind, expr.is_some())
834            }
835            AssocItemKind::Fn(box Fn {
836                sig, ident, generics, body: None, define_opaque, ..
837            }) => {
838                // FIXME(contracts): Deny contract here since it won't apply to
839                // any impl method or callees.
840                let idents = self.lower_fn_params_to_idents(&sig.decl);
841                let (generics, sig) = self.lower_method_sig(
842                    generics,
843                    sig,
844                    i.id,
845                    FnDeclKind::Trait,
846                    sig.header.coroutine_kind,
847                    attrs,
848                );
849                if define_opaque.is_some() {
850                    self.dcx().span_err(
851                        i.span,
852                        "only trait methods with default bodies can define opaque types",
853                    );
854                }
855                (
856                    *ident,
857                    generics,
858                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),
859                    false,
860                )
861            }
862            AssocItemKind::Fn(box Fn {
863                sig,
864                ident,
865                generics,
866                body: Some(body),
867                contract,
868                define_opaque,
869                ..
870            }) => {
871                let body_id = self.lower_maybe_coroutine_body(
872                    sig.span,
873                    i.span,
874                    hir_id,
875                    &sig.decl,
876                    sig.header.coroutine_kind,
877                    Some(body),
878                    attrs,
879                    contract.as_deref(),
880                );
881                let (generics, sig) = self.lower_method_sig(
882                    generics,
883                    sig,
884                    i.id,
885                    FnDeclKind::Trait,
886                    sig.header.coroutine_kind,
887                    attrs,
888                );
889                self.lower_define_opaque(hir_id, &define_opaque);
890                (
891                    *ident,
892                    generics,
893                    hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
894                    true,
895                )
896            }
897            AssocItemKind::Type(box TyAlias {
898                ident, generics, where_clauses, bounds, ty, ..
899            }) => {
900                let mut generics = generics.clone();
901                add_ty_alias_where_clause(&mut generics, *where_clauses, false);
902                let (generics, kind) = self.lower_generics(
903                    &generics,
904                    i.id,
905                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
906                    |this| {
907                        let ty = ty.as_ref().map(|x| {
908                            this.lower_ty(
909                                x,
910                                ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
911                            )
912                        });
913                        hir::TraitItemKind::Type(
914                            this.lower_param_bounds(
915                                bounds,
916                                ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
917                            ),
918                            ty,
919                        )
920                    },
921                );
922                (*ident, generics, kind, ty.is_some())
923            }
924            AssocItemKind::Delegation(box delegation) => {
925                let delegation_results = self.lower_delegation(delegation, i.id, false);
926                let item_kind = hir::TraitItemKind::Fn(
927                    delegation_results.sig,
928                    hir::TraitFn::Provided(delegation_results.body_id),
929                );
930                (delegation.ident, delegation_results.generics, item_kind, true)
931            }
932            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
933                panic!("macros should have been expanded by now")
934            }
935        };
936
937        let item = hir::TraitItem {
938            owner_id: trait_item_def_id,
939            ident: self.lower_ident(ident),
940            generics,
941            kind,
942            span: self.lower_span(i.span),
943            defaultness: hir::Defaultness::Default { has_value: has_default },
944        };
945        self.arena.alloc(item)
946    }
947
948    fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
949        let (ident, kind) = match &i.kind {
950            AssocItemKind::Const(box ConstItem { ident, .. }) => {
951                (*ident, hir::AssocItemKind::Const)
952            }
953            AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
954            AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
955                (*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
956            }
957            AssocItemKind::Delegation(box delegation) => (
958                delegation.ident,
959                hir::AssocItemKind::Fn {
960                    has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
961                },
962            ),
963            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
964                panic!("macros should have been expanded by now")
965            }
966        };
967        let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
968        hir::TraitItemRef {
969            id,
970            ident: self.lower_ident(ident),
971            span: self.lower_span(i.span),
972            kind,
973        }
974    }
975
976    /// Construct `ExprKind::Err` for the given `span`.
977    pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {
978        self.expr(span, hir::ExprKind::Err(guar))
979    }
980
981    fn lower_impl_item(
982        &mut self,
983        i: &AssocItem,
984        is_in_trait_impl: bool,
985    ) -> &'hir hir::ImplItem<'hir> {
986        // Since `default impl` is not yet implemented, this is always true in impls.
987        let has_value = true;
988        let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
989        let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
990        let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
991
992        let (ident, (generics, kind)) = match &i.kind {
993            AssocItemKind::Const(box ConstItem {
994                ident,
995                generics,
996                ty,
997                expr,
998                define_opaque,
999                ..
1000            }) => (
1001                *ident,
1002                self.lower_generics(
1003                    generics,
1004                    i.id,
1005                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1006                    |this| {
1007                        let ty = this
1008                            .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1009                        let body = this.lower_const_body(i.span, expr.as_deref());
1010                        this.lower_define_opaque(hir_id, &define_opaque);
1011                        hir::ImplItemKind::Const(ty, body)
1012                    },
1013                ),
1014            ),
1015            AssocItemKind::Fn(box Fn {
1016                sig,
1017                ident,
1018                generics,
1019                body,
1020                contract,
1021                define_opaque,
1022                ..
1023            }) => {
1024                let body_id = self.lower_maybe_coroutine_body(
1025                    sig.span,
1026                    i.span,
1027                    hir_id,
1028                    &sig.decl,
1029                    sig.header.coroutine_kind,
1030                    body.as_deref(),
1031                    attrs,
1032                    contract.as_deref(),
1033                );
1034                let (generics, sig) = self.lower_method_sig(
1035                    generics,
1036                    sig,
1037                    i.id,
1038                    if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
1039                    sig.header.coroutine_kind,
1040                    attrs,
1041                );
1042                self.lower_define_opaque(hir_id, &define_opaque);
1043
1044                (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
1045            }
1046            AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
1047                let mut generics = generics.clone();
1048                add_ty_alias_where_clause(&mut generics, *where_clauses, false);
1049                (
1050                    *ident,
1051                    self.lower_generics(
1052                        &generics,
1053                        i.id,
1054                        ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1055                        |this| match ty {
1056                            None => {
1057                                let guar = this.dcx().span_delayed_bug(
1058                                    i.span,
1059                                    "expected to lower associated type, but it was missing",
1060                                );
1061                                let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
1062                                hir::ImplItemKind::Type(ty)
1063                            }
1064                            Some(ty) => {
1065                                let ty = this.lower_ty(
1066                                    ty,
1067                                    ImplTraitContext::OpaqueTy {
1068                                        origin: hir::OpaqueTyOrigin::TyAlias {
1069                                            parent: this.local_def_id(i.id),
1070                                            in_assoc_ty: true,
1071                                        },
1072                                    },
1073                                );
1074                                hir::ImplItemKind::Type(ty)
1075                            }
1076                        },
1077                    ),
1078                )
1079            }
1080            AssocItemKind::Delegation(box delegation) => {
1081                let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
1082                (
1083                    delegation.ident,
1084                    (
1085                        delegation_results.generics,
1086                        hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
1087                    ),
1088                )
1089            }
1090            AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1091                panic!("macros should have been expanded by now")
1092            }
1093        };
1094
1095        let item = hir::ImplItem {
1096            owner_id: hir_id.expect_owner(),
1097            ident: self.lower_ident(ident),
1098            generics,
1099            kind,
1100            vis_span: self.lower_span(i.vis.span),
1101            span: self.lower_span(i.span),
1102            defaultness,
1103        };
1104        self.arena.alloc(item)
1105    }
1106
1107    fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
1108        hir::ImplItemRef {
1109            id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
1110            // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
1111            // assoc item kinds without an identifier and they cannot reach here.
1112            ident: self.lower_ident(i.kind.ident().unwrap()),
1113            span: self.lower_span(i.span),
1114            kind: match &i.kind {
1115                AssocItemKind::Const(..) => hir::AssocItemKind::Const,
1116                AssocItemKind::Type(..) => hir::AssocItemKind::Type,
1117                AssocItemKind::Fn(box Fn { sig, .. }) => {
1118                    hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
1119                }
1120                AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
1121                    has_self: self.delegatee_is_method(
1122                        i.id,
1123                        delegation.id,
1124                        i.span,
1125                        is_in_trait_impl,
1126                    ),
1127                },
1128                AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1129                    panic!("macros should have been expanded by now")
1130                }
1131            },
1132            trait_item_def_id: self
1133                .resolver
1134                .get_partial_res(i.id)
1135                .map(|r| r.expect_full_res().opt_def_id())
1136                .unwrap_or(None),
1137        }
1138    }
1139
1140    fn lower_defaultness(
1141        &self,
1142        d: Defaultness,
1143        has_value: bool,
1144    ) -> (hir::Defaultness, Option<Span>) {
1145        match d {
1146            Defaultness::Default(sp) => {
1147                (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
1148            }
1149            Defaultness::Final => {
1150                assert!(has_value);
1151                (hir::Defaultness::Final, None)
1152            }
1153        }
1154    }
1155
1156    fn record_body(
1157        &mut self,
1158        params: &'hir [hir::Param<'hir>],
1159        value: hir::Expr<'hir>,
1160    ) -> hir::BodyId {
1161        let body = hir::Body { params, value: self.arena.alloc(value) };
1162        let id = body.id();
1163        assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
1164        self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
1165        id
1166    }
1167
1168    pub(super) fn lower_body(
1169        &mut self,
1170        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
1171    ) -> hir::BodyId {
1172        let prev_coroutine_kind = self.coroutine_kind.take();
1173        let task_context = self.task_context.take();
1174        let (parameters, result) = f(self);
1175        let body_id = self.record_body(parameters, result);
1176        self.task_context = task_context;
1177        self.coroutine_kind = prev_coroutine_kind;
1178        body_id
1179    }
1180
1181    fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1182        let hir_id = self.lower_node_id(param.id);
1183        self.lower_attrs(hir_id, &param.attrs, param.span);
1184        hir::Param {
1185            hir_id,
1186            pat: self.lower_pat(&param.pat),
1187            ty_span: self.lower_span(param.ty.span),
1188            span: self.lower_span(param.span),
1189        }
1190    }
1191
1192    pub(super) fn lower_fn_body(
1193        &mut self,
1194        decl: &FnDecl,
1195        contract: Option<&FnContract>,
1196        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
1197    ) -> hir::BodyId {
1198        self.lower_body(|this| {
1199            let params =
1200                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
1201
1202            // Optionally lower the fn contract, which turns:
1203            //
1204            // { body }
1205            //
1206            // into:
1207            //
1208            // { contract_requires(PRECOND); let __postcond = |ret_val| POSTCOND; postcond({ body }) }
1209            if let Some(contract) = contract {
1210                let precond = if let Some(req) = &contract.requires {
1211                    // Lower the precondition check intrinsic.
1212                    let lowered_req = this.lower_expr_mut(&req);
1213                    let req_span = this.mark_span_with_reason(
1214                        DesugaringKind::Contract,
1215                        lowered_req.span,
1216                        None,
1217                    );
1218                    let precond = this.expr_call_lang_item_fn_mut(
1219                        req_span,
1220                        hir::LangItem::ContractCheckRequires,
1221                        &*arena_vec![this; lowered_req],
1222                    );
1223                    Some(this.stmt_expr(req.span, precond))
1224                } else {
1225                    None
1226                };
1227                let (postcond, body) = if let Some(ens) = &contract.ensures {
1228                    let ens_span = this.lower_span(ens.span);
1229                    let ens_span =
1230                        this.mark_span_with_reason(DesugaringKind::Contract, ens_span, None);
1231                    // Set up the postcondition `let` statement.
1232                    let check_ident: Ident =
1233                        Ident::from_str_and_span("__ensures_checker", ens_span);
1234                    let (checker_pat, check_hir_id) = this.pat_ident_binding_mode_mut(
1235                        ens_span,
1236                        check_ident,
1237                        hir::BindingMode::NONE,
1238                    );
1239                    let lowered_ens = this.lower_expr_mut(&ens);
1240                    let postcond_checker = this.expr_call_lang_item_fn(
1241                        ens_span,
1242                        hir::LangItem::ContractBuildCheckEnsures,
1243                        &*arena_vec![this; lowered_ens],
1244                    );
1245                    let postcond = this.stmt_let_pat(
1246                        None,
1247                        ens_span,
1248                        Some(postcond_checker),
1249                        this.arena.alloc(checker_pat),
1250                        hir::LocalSource::Contract,
1251                    );
1252
1253                    // Install contract_ensures so we will intercept `return` statements,
1254                    // then lower the body.
1255                    this.contract_ensures = Some((ens_span, check_ident, check_hir_id));
1256                    let body = this.arena.alloc(body(this));
1257
1258                    // Finally, inject an ensures check on the implicit return of the body.
1259                    let body = this.inject_ensures_check(body, ens_span, check_ident, check_hir_id);
1260                    (Some(postcond), body)
1261                } else {
1262                    let body = &*this.arena.alloc(body(this));
1263                    (None, body)
1264                };
1265                // Flatten the body into precond, then postcond, then wrapped body.
1266                let wrapped_body = this.block_all(
1267                    body.span,
1268                    this.arena.alloc_from_iter([precond, postcond].into_iter().flatten()),
1269                    Some(body),
1270                );
1271                (params, this.expr_block(wrapped_body))
1272            } else {
1273                (params, body(this))
1274            }
1275        })
1276    }
1277
1278    fn lower_fn_body_block(
1279        &mut self,
1280        decl: &FnDecl,
1281        body: &Block,
1282        contract: Option<&FnContract>,
1283    ) -> hir::BodyId {
1284        self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
1285    }
1286
1287    pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1288        self.lower_body(|this| {
1289            (
1290                &[],
1291                match expr {
1292                    Some(expr) => this.lower_expr_mut(expr),
1293                    None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
1294                },
1295            )
1296        })
1297    }
1298
1299    /// Takes what may be the body of an `async fn` or a `gen fn` and wraps it in an `async {}` or
1300    /// `gen {}` block as appropriate.
1301    fn lower_maybe_coroutine_body(
1302        &mut self,
1303        fn_decl_span: Span,
1304        span: Span,
1305        fn_id: hir::HirId,
1306        decl: &FnDecl,
1307        coroutine_kind: Option<CoroutineKind>,
1308        body: Option<&Block>,
1309        attrs: &'hir [hir::Attribute],
1310        contract: Option<&FnContract>,
1311    ) -> hir::BodyId {
1312        let Some(body) = body else {
1313            // Functions without a body are an error, except if this is an intrinsic. For those we
1314            // create a fake body so that the entire rest of the compiler doesn't have to deal with
1315            // this as a special case.
1316            return self.lower_fn_body(decl, contract, |this| {
1317                if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
1318                    || this.tcx.is_sdylib_interface_build()
1319                {
1320                    let span = this.lower_span(span);
1321                    let empty_block = hir::Block {
1322                        hir_id: this.next_id(),
1323                        stmts: &[],
1324                        expr: None,
1325                        rules: hir::BlockCheckMode::DefaultBlock,
1326                        span,
1327                        targeted_by_break: false,
1328                    };
1329                    let loop_ = hir::ExprKind::Loop(
1330                        this.arena.alloc(empty_block),
1331                        None,
1332                        hir::LoopSource::Loop,
1333                        span,
1334                    );
1335                    hir::Expr { hir_id: this.next_id(), kind: loop_, span }
1336                } else {
1337                    this.expr_err(span, this.dcx().has_errors().unwrap())
1338                }
1339            });
1340        };
1341        let Some(coroutine_kind) = coroutine_kind else {
1342            // Typical case: not a coroutine.
1343            return self.lower_fn_body_block(decl, body, contract);
1344        };
1345        // FIXME(contracts): Support contracts on async fn.
1346        self.lower_body(|this| {
1347            let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1348                decl,
1349                |this| this.lower_block_expr(body),
1350                fn_decl_span,
1351                body.span,
1352                coroutine_kind,
1353                hir::CoroutineSource::Fn,
1354            );
1355
1356            // FIXME(async_fn_track_caller): Can this be moved above?
1357            let hir_id = expr.hir_id;
1358            this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1359
1360            (parameters, expr)
1361        })
1362    }
1363
1364    /// Lowers a desugared coroutine body after moving all of the arguments
1365    /// into the body. This is to make sure that the future actually owns the
1366    /// arguments that are passed to the function, and to ensure things like
1367    /// drop order are stable.
1368    pub(crate) fn lower_coroutine_body_with_moved_arguments(
1369        &mut self,
1370        decl: &FnDecl,
1371        lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
1372        fn_decl_span: Span,
1373        body_span: Span,
1374        coroutine_kind: CoroutineKind,
1375        coroutine_source: hir::CoroutineSource,
1376    ) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {
1377        let mut parameters: Vec<hir::Param<'_>> = Vec::new();
1378        let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
1379
1380        // Async function parameters are lowered into the closure body so that they are
1381        // captured and so that the drop order matches the equivalent non-async functions.
1382        //
1383        // from:
1384        //
1385        //     async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
1386        //         <body>
1387        //     }
1388        //
1389        // into:
1390        //
1391        //     fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
1392        //       async move {
1393        //         let __arg2 = __arg2;
1394        //         let <pattern> = __arg2;
1395        //         let __arg1 = __arg1;
1396        //         let <pattern> = __arg1;
1397        //         let __arg0 = __arg0;
1398        //         let <pattern> = __arg0;
1399        //         drop-temps { <body> } // see comments later in fn for details
1400        //       }
1401        //     }
1402        //
1403        // If `<pattern>` is a simple ident, then it is lowered to a single
1404        // `let <pattern> = <pattern>;` statement as an optimization.
1405        //
1406        // Note that the body is embedded in `drop-temps`; an
1407        // equivalent desugaring would be `return { <body>
1408        // };`. The key point is that we wish to drop all the
1409        // let-bound variables and temporaries created in the body
1410        // (and its tail expression!) before we drop the
1411        // parameters (c.f. rust-lang/rust#64512).
1412        for (index, parameter) in decl.inputs.iter().enumerate() {
1413            let parameter = self.lower_param(parameter);
1414            let span = parameter.pat.span;
1415
1416            // Check if this is a binding pattern, if so, we can optimize and avoid adding a
1417            // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
1418            let (ident, is_simple_parameter) = match parameter.pat.kind {
1419                hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),
1420                // For `ref mut` or wildcard arguments, we can't reuse the binding, but
1421                // we can keep the same name for the parameter.
1422                // This lets rustdoc render it correctly in documentation.
1423                hir::PatKind::Binding(_, _, ident, _) => (ident, false),
1424                hir::PatKind::Wild => (Ident::with_dummy_span(rustc_span::kw::Underscore), false),
1425                _ => {
1426                    // Replace the ident for bindings that aren't simple.
1427                    let name = format!("__arg{index}");
1428                    let ident = Ident::from_str(&name);
1429
1430                    (ident, false)
1431                }
1432            };
1433
1434            let desugared_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1435
1436            // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
1437            // async function.
1438            //
1439            // If this is the simple case, this parameter will end up being the same as the
1440            // original parameter, but with a different pattern id.
1441            let stmt_attrs = self.attrs.get(&parameter.hir_id.local_id).copied();
1442            let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident);
1443            let new_parameter = hir::Param {
1444                hir_id: parameter.hir_id,
1445                pat: new_parameter_pat,
1446                ty_span: self.lower_span(parameter.ty_span),
1447                span: self.lower_span(parameter.span),
1448            };
1449
1450            if is_simple_parameter {
1451                // If this is the simple case, then we only insert one statement that is
1452                // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
1453                // `HirId`s are densely assigned.
1454                let expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1455                let stmt = self.stmt_let_pat(
1456                    stmt_attrs,
1457                    desugared_span,
1458                    Some(expr),
1459                    parameter.pat,
1460                    hir::LocalSource::AsyncFn,
1461                );
1462                statements.push(stmt);
1463            } else {
1464                // If this is not the simple case, then we construct two statements:
1465                //
1466                // ```
1467                // let __argN = __argN;
1468                // let <pat> = __argN;
1469                // ```
1470                //
1471                // The first statement moves the parameter into the closure and thus ensures
1472                // that the drop order is correct.
1473                //
1474                // The second statement creates the bindings that the user wrote.
1475
1476                // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
1477                // because the user may have specified a `ref mut` binding in the next
1478                // statement.
1479                let (move_pat, move_id) =
1480                    self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);
1481                let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1482                let move_stmt = self.stmt_let_pat(
1483                    None,
1484                    desugared_span,
1485                    Some(move_expr),
1486                    move_pat,
1487                    hir::LocalSource::AsyncFn,
1488                );
1489
1490                // Construct the `let <pat> = __argN;` statement. We re-use the original
1491                // parameter's pattern so that `HirId`s are densely assigned.
1492                let pattern_expr = self.expr_ident(desugared_span, ident, move_id);
1493                let pattern_stmt = self.stmt_let_pat(
1494                    stmt_attrs,
1495                    desugared_span,
1496                    Some(pattern_expr),
1497                    parameter.pat,
1498                    hir::LocalSource::AsyncFn,
1499                );
1500
1501                statements.push(move_stmt);
1502                statements.push(pattern_stmt);
1503            };
1504
1505            parameters.push(new_parameter);
1506        }
1507
1508        let mkbody = |this: &mut LoweringContext<'_, 'hir>| {
1509            // Create a block from the user's function body:
1510            let user_body = lower_body(this);
1511
1512            // Transform into `drop-temps { <user-body> }`, an expression:
1513            let desugared_span =
1514                this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
1515            let user_body = this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
1516
1517            // As noted above, create the final block like
1518            //
1519            // ```
1520            // {
1521            //   let $param_pattern = $raw_param;
1522            //   ...
1523            //   drop-temps { <user-body> }
1524            // }
1525            // ```
1526            let body = this.block_all(
1527                desugared_span,
1528                this.arena.alloc_from_iter(statements),
1529                Some(user_body),
1530            );
1531
1532            this.expr_block(body)
1533        };
1534        let desugaring_kind = match coroutine_kind {
1535            CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,
1536            CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,
1537            CoroutineKind::AsyncGen { .. } => hir::CoroutineDesugaring::AsyncGen,
1538        };
1539        let closure_id = coroutine_kind.closure_id();
1540
1541        let coroutine_expr = self.make_desugared_coroutine_expr(
1542            // The default capture mode here is by-ref. Later on during upvar analysis,
1543            // we will force the captured arguments to by-move, but for async closures,
1544            // we want to make sure that we avoid unnecessarily moving captures, or else
1545            // all async closures would default to `FnOnce` as their calling mode.
1546            CaptureBy::Ref,
1547            closure_id,
1548            None,
1549            fn_decl_span,
1550            body_span,
1551            desugaring_kind,
1552            coroutine_source,
1553            mkbody,
1554        );
1555
1556        let expr = hir::Expr {
1557            hir_id: self.lower_node_id(closure_id),
1558            kind: coroutine_expr,
1559            span: self.lower_span(body_span),
1560        };
1561
1562        (self.arena.alloc_from_iter(parameters), expr)
1563    }
1564
1565    fn lower_method_sig(
1566        &mut self,
1567        generics: &Generics,
1568        sig: &FnSig,
1569        id: NodeId,
1570        kind: FnDeclKind,
1571        coroutine_kind: Option<CoroutineKind>,
1572        attrs: &[hir::Attribute],
1573    ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
1574        let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
1575        let itctx = ImplTraitContext::Universal;
1576        let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1577            this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1578        });
1579        (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
1580    }
1581
1582    pub(super) fn lower_fn_header(
1583        &mut self,
1584        h: FnHeader,
1585        default_safety: hir::Safety,
1586        attrs: &[hir::Attribute],
1587    ) -> hir::FnHeader {
1588        let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
1589            hir::IsAsync::Async(span)
1590        } else {
1591            hir::IsAsync::NotAsync
1592        };
1593
1594        let safety = self.lower_safety(h.safety, default_safety);
1595
1596        // Treat safe `#[target_feature]` functions as unsafe, but also remember that we did so.
1597        let safety = if attrs.iter().any(|attr| attr.has_name(sym::target_feature))
1598            && safety.is_safe()
1599            && !self.tcx.sess.target.is_like_wasm
1600        {
1601            hir::HeaderSafety::SafeTargetFeatures
1602        } else {
1603            safety.into()
1604        };
1605
1606        hir::FnHeader {
1607            safety,
1608            asyncness,
1609            constness: self.lower_constness(h.constness),
1610            abi: self.lower_extern(h.ext),
1611        }
1612    }
1613
1614    pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {
1615        let ast::StrLit { symbol_unescaped, span, .. } = abi_str;
1616        let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| {
1617            self.error_on_invalid_abi(abi_str);
1618            ExternAbi::Rust
1619        });
1620        let sess = self.tcx.sess;
1621        let features = self.tcx.features();
1622        gate_unstable_abi(sess, features, span, extern_abi);
1623        extern_abi
1624    }
1625
1626    pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {
1627        match ext {
1628            Extern::None => ExternAbi::Rust,
1629            Extern::Implicit(_) => ExternAbi::FALLBACK,
1630            Extern::Explicit(abi, _) => self.lower_abi(abi),
1631        }
1632    }
1633
1634    fn error_on_invalid_abi(&self, abi: StrLit) {
1635        let abi_names = enabled_names(self.tcx.features(), abi.span)
1636            .iter()
1637            .map(|s| Symbol::intern(s))
1638            .collect::<Vec<_>>();
1639        let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
1640        self.dcx().emit_err(InvalidAbi {
1641            abi: abi.symbol_unescaped,
1642            span: abi.span,
1643            suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
1644                span: abi.span,
1645                suggestion: suggested_name.to_string(),
1646            }),
1647            command: "rustc --print=calling-conventions".to_string(),
1648        });
1649    }
1650
1651    pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
1652        match c {
1653            Const::Yes(_) => hir::Constness::Const,
1654            Const::No => hir::Constness::NotConst,
1655        }
1656    }
1657
1658    pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {
1659        match s {
1660            Safety::Unsafe(_) => hir::Safety::Unsafe,
1661            Safety::Default => default,
1662            Safety::Safe(_) => hir::Safety::Safe,
1663        }
1664    }
1665
1666    /// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with
1667    /// the carried impl trait definitions and bounds.
1668    #[instrument(level = "debug", skip(self, f))]
1669    fn lower_generics<T>(
1670        &mut self,
1671        generics: &Generics,
1672        parent_node_id: NodeId,
1673        itctx: ImplTraitContext,
1674        f: impl FnOnce(&mut Self) -> T,
1675    ) -> (&'hir hir::Generics<'hir>, T) {
1676        assert!(self.impl_trait_defs.is_empty());
1677        assert!(self.impl_trait_bounds.is_empty());
1678
1679        // Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
1680        // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
1681        // these into hir when we lower thee where clauses), but this makes it quite difficult to
1682        // keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
1683        // checks both param bounds and where clauses for `?Sized`.
1684        for pred in &generics.where_clause.predicates {
1685            let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else {
1686                continue;
1687            };
1688            let compute_is_param = || {
1689                // Check if the where clause type is a plain type parameter.
1690                match self
1691                    .resolver
1692                    .get_partial_res(bound_pred.bounded_ty.id)
1693                    .and_then(|r| r.full_res())
1694                {
1695                    Some(Res::Def(DefKind::TyParam, def_id))
1696                        if bound_pred.bound_generic_params.is_empty() =>
1697                    {
1698                        generics
1699                            .params
1700                            .iter()
1701                            .any(|p| def_id == self.local_def_id(p.id).to_def_id())
1702                    }
1703                    // Either the `bounded_ty` is not a plain type parameter, or
1704                    // it's not found in the generic type parameters list.
1705                    _ => false,
1706                }
1707            };
1708            // We only need to compute this once per `WherePredicate`, but don't
1709            // need to compute this at all unless there is a Maybe bound.
1710            let mut is_param: Option<bool> = None;
1711            for bound in &bound_pred.bounds {
1712                if !matches!(
1713                    *bound,
1714                    GenericBound::Trait(PolyTraitRef {
1715                        modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
1716                        ..
1717                    })
1718                ) {
1719                    continue;
1720                }
1721                let is_param = *is_param.get_or_insert_with(compute_is_param);
1722                if !is_param && !self.tcx.features().more_maybe_bounds() {
1723                    self.tcx
1724                        .sess
1725                        .create_feature_err(
1726                            MisplacedRelaxTraitBound { span: bound.span() },
1727                            sym::more_maybe_bounds,
1728                        )
1729                        .emit();
1730                }
1731            }
1732        }
1733
1734        let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
1735        predicates.extend(generics.params.iter().filter_map(|param| {
1736            self.lower_generic_bound_predicate(
1737                param.ident,
1738                param.id,
1739                &param.kind,
1740                &param.bounds,
1741                param.colon_span,
1742                generics.span,
1743                itctx,
1744                PredicateOrigin::GenericParam,
1745            )
1746        }));
1747        predicates.extend(
1748            generics
1749                .where_clause
1750                .predicates
1751                .iter()
1752                .map(|predicate| self.lower_where_predicate(predicate)),
1753        );
1754
1755        let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self
1756            .lower_generic_params_mut(&generics.params, hir::GenericParamSource::Generics)
1757            .collect();
1758
1759        // Introduce extra lifetimes if late resolution tells us to.
1760        let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);
1761        params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
1762            self.lifetime_res_to_generic_param(
1763                ident,
1764                node_id,
1765                res,
1766                hir::GenericParamSource::Generics,
1767            )
1768        }));
1769
1770        let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();
1771        let where_clause_span = self.lower_span(generics.where_clause.span);
1772        let span = self.lower_span(generics.span);
1773        let res = f(self);
1774
1775        let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
1776        params.extend(impl_trait_defs.into_iter());
1777
1778        let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
1779        predicates.extend(impl_trait_bounds.into_iter());
1780
1781        let lowered_generics = self.arena.alloc(hir::Generics {
1782            params: self.arena.alloc_from_iter(params),
1783            predicates: self.arena.alloc_from_iter(predicates),
1784            has_where_clause_predicates,
1785            where_clause_span,
1786            span,
1787        });
1788
1789        (lowered_generics, res)
1790    }
1791
1792    pub(super) fn lower_define_opaque(
1793        &mut self,
1794        hir_id: HirId,
1795        define_opaque: &Option<ThinVec<(NodeId, Path)>>,
1796    ) {
1797        assert_eq!(self.define_opaque, None);
1798        assert!(hir_id.is_owner());
1799        let Some(define_opaque) = define_opaque.as_ref() else {
1800            return;
1801        };
1802        let define_opaque = define_opaque.iter().filter_map(|(id, path)| {
1803            let res = self.resolver.get_partial_res(*id);
1804            let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {
1805                self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
1806                return None;
1807            };
1808            let Some(did) = did.as_local() else {
1809                self.dcx().span_err(
1810                    path.span,
1811                    "only opaque types defined in the local crate can be defined",
1812                );
1813                return None;
1814            };
1815            Some((self.lower_span(path.span), did))
1816        });
1817        let define_opaque = self.arena.alloc_from_iter(define_opaque);
1818        self.define_opaque = Some(define_opaque);
1819    }
1820
1821    pub(super) fn lower_generic_bound_predicate(
1822        &mut self,
1823        ident: Ident,
1824        id: NodeId,
1825        kind: &GenericParamKind,
1826        bounds: &[GenericBound],
1827        colon_span: Option<Span>,
1828        parent_span: Span,
1829        itctx: ImplTraitContext,
1830        origin: PredicateOrigin,
1831    ) -> Option<hir::WherePredicate<'hir>> {
1832        // Do not create a clause if we do not have anything inside it.
1833        if bounds.is_empty() {
1834            return None;
1835        }
1836
1837        let bounds = self.lower_param_bounds(bounds, itctx);
1838
1839        let param_span = ident.span;
1840
1841        // Reconstruct the span of the entire predicate from the individual generic bounds.
1842        let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());
1843        let span = bounds.iter().fold(span_start, |span_accum, bound| {
1844            match bound.span().find_ancestor_inside(parent_span) {
1845                Some(bound_span) => span_accum.to(bound_span),
1846                None => span_accum,
1847            }
1848        });
1849        let span = self.lower_span(span);
1850        let hir_id = self.next_id();
1851        let kind = self.arena.alloc(match kind {
1852            GenericParamKind::Const { .. } => return None,
1853            GenericParamKind::Type { .. } => {
1854                let def_id = self.local_def_id(id).to_def_id();
1855                let hir_id = self.next_id();
1856                let res = Res::Def(DefKind::TyParam, def_id);
1857                let ident = self.lower_ident(ident);
1858                let ty_path = self.arena.alloc(hir::Path {
1859                    span: param_span,
1860                    res,
1861                    segments: self
1862                        .arena
1863                        .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
1864                });
1865                let ty_id = self.next_id();
1866                let bounded_ty =
1867                    self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
1868                hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1869                    bounded_ty: self.arena.alloc(bounded_ty),
1870                    bounds,
1871                    bound_generic_params: &[],
1872                    origin,
1873                })
1874            }
1875            GenericParamKind::Lifetime => {
1876                let lt_id = self.next_node_id();
1877                let lifetime =
1878                    self.new_named_lifetime(id, lt_id, ident, LifetimeSource::Other, ident.into());
1879                hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1880                    lifetime,
1881                    bounds,
1882                    in_where_clause: false,
1883                })
1884            }
1885        });
1886        Some(hir::WherePredicate { hir_id, span, kind })
1887    }
1888
1889    fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
1890        let hir_id = self.lower_node_id(pred.id);
1891        let span = self.lower_span(pred.span);
1892        self.lower_attrs(hir_id, &pred.attrs, span);
1893        let kind = self.arena.alloc(match &pred.kind {
1894            WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1895                bound_generic_params,
1896                bounded_ty,
1897                bounds,
1898            }) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1899                bound_generic_params: self
1900                    .lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
1901                bounded_ty: self
1902                    .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1903                bounds: self.lower_param_bounds(
1904                    bounds,
1905                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1906                ),
1907                origin: PredicateOrigin::WhereClause,
1908            }),
1909            WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
1910                hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1911                    lifetime: self.lower_lifetime(
1912                        lifetime,
1913                        LifetimeSource::Other,
1914                        lifetime.ident.into(),
1915                    ),
1916                    bounds: self.lower_param_bounds(
1917                        bounds,
1918                        ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1919                    ),
1920                    in_where_clause: true,
1921                })
1922            }
1923            WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
1924                hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
1925                    lhs_ty: self
1926                        .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1927                    rhs_ty: self
1928                        .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1929                })
1930            }
1931        });
1932        hir::WherePredicate { hir_id, span, kind }
1933    }
1934}