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, 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::ty::{ResolverAstLowering, TyCtxt};
11use rustc_span::edit_distance::find_best_match_for_name;
12use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
13use smallvec::{SmallVec, smallvec};
14use thin_vec::ThinVec;
15use tracing::instrument;
16
17use super::errors::{
18 InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound, TupleStructWithDefault,
19};
20use super::stability::{enabled_names, gate_unstable_abi};
21use super::{
22 AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
23 ResolverAstLoweringExt,
24};
25
26pub(super) struct ItemLowerer<'a, 'hir> {
27 pub(super) tcx: TyCtxt<'hir>,
28 pub(super) resolver: &'a mut ResolverAstLowering,
29 pub(super) ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,
30 pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<'hir>>,
31}
32
33fn add_ty_alias_where_clause(
37 generics: &mut ast::Generics,
38 mut where_clauses: TyAliasWhereClauses,
39 prefer_first: bool,
40) {
41 if !prefer_first {
42 (where_clauses.before, where_clauses.after) = (where_clauses.after, where_clauses.before);
43 }
44 let where_clause =
45 if where_clauses.before.has_where_token || !where_clauses.after.has_where_token {
46 where_clauses.before
47 } else {
48 where_clauses.after
49 };
50 generics.where_clause.has_where_token = where_clause.has_where_token;
51 generics.where_clause.span = where_clause.span;
52}
53
54impl<'a, 'hir> ItemLowerer<'a, 'hir> {
55 fn with_lctx(
56 &mut self,
57 owner: NodeId,
58 f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>,
59 ) {
60 let mut lctx = LoweringContext::new(self.tcx, self.resolver);
61 lctx.with_hir_id_owner(owner, |lctx| f(lctx));
62
63 for (def_id, info) in lctx.children {
64 let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
65 debug_assert!(
66 matches!(owner, hir::MaybeOwner::Phantom),
67 "duplicate copy of {def_id:?} in lctx.children"
68 );
69 *owner = info;
70 }
71 }
72
73 pub(super) fn lower_node(&mut self, def_id: LocalDefId) -> hir::MaybeOwner<'hir> {
74 let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
75 if let hir::MaybeOwner::Phantom = owner {
76 let node = self.ast_index[def_id];
77 match node {
78 AstOwner::NonOwner => {}
79 AstOwner::Crate(c) => self.lower_crate(c),
80 AstOwner::Item(item) => self.lower_item(item),
81 AstOwner::AssocItem(item, ctxt) => self.lower_assoc_item(item, ctxt),
82 AstOwner::ForeignItem(item) => self.lower_foreign_item(item),
83 }
84 }
85
86 self.owners[def_id]
87 }
88
89 #[instrument(level = "debug", skip(self, c))]
90 fn lower_crate(&mut self, c: &Crate) {
91 debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
92 self.with_lctx(CRATE_NODE_ID, |lctx| {
93 let module = lctx.lower_mod(&c.items, &c.spans);
94 lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
96 hir::OwnerNode::Crate(module)
97 })
98 }
99
100 #[instrument(level = "debug", skip(self))]
101 fn lower_item(&mut self, item: &Item) {
102 self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
103 }
104
105 fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
106 self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
107 }
108
109 fn lower_foreign_item(&mut self, item: &ForeignItem) {
110 self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
111 }
112}
113
114impl<'hir> LoweringContext<'_, 'hir> {
115 pub(super) fn lower_mod(
116 &mut self,
117 items: &[P<Item>],
118 spans: &ModSpans,
119 ) -> &'hir hir::Mod<'hir> {
120 self.arena.alloc(hir::Mod {
121 spans: hir::ModSpans {
122 inner_span: self.lower_span(spans.inner_span),
123 inject_use_span: self.lower_span(spans.inject_use_span),
124 },
125 item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
126 })
127 }
128
129 pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
130 let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }];
131 if let ItemKind::Use(use_tree) = &i.kind {
132 self.lower_item_id_use_tree(use_tree, &mut node_ids);
133 }
134 node_ids
135 }
136
137 fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
138 match &tree.kind {
139 UseTreeKind::Nested { items, .. } => {
140 for &(ref nested, id) in items {
141 vec.push(hir::ItemId { owner_id: self.owner_id(id) });
142 self.lower_item_id_use_tree(nested, vec);
143 }
144 }
145 UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
146 }
147 }
148
149 fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
150 let vis_span = self.lower_span(i.vis.span);
151 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
152 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
153 let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
154 let item = hir::Item {
155 owner_id: hir_id.expect_owner(),
156 kind,
157 vis_span,
158 span: self.lower_span(i.span),
159 };
160 self.arena.alloc(item)
161 }
162
163 fn lower_item_kind(
164 &mut self,
165 span: Span,
166 id: NodeId,
167 hir_id: hir::HirId,
168 attrs: &'hir [hir::Attribute],
169 vis_span: Span,
170 i: &ItemKind,
171 ) -> hir::ItemKind<'hir> {
172 match i {
173 ItemKind::ExternCrate(orig_name, ident) => {
174 let ident = self.lower_ident(*ident);
175 hir::ItemKind::ExternCrate(*orig_name, ident)
176 }
177 ItemKind::Use(use_tree) => {
178 let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
180
181 self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
182 }
183 ItemKind::Static(box ast::StaticItem {
184 ident,
185 ty: t,
186 safety: _,
187 mutability: m,
188 expr: e,
189 define_opaque,
190 }) => {
191 let ident = self.lower_ident(*ident);
192 let (ty, body_id) =
193 self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
194 self.lower_define_opaque(hir_id, define_opaque);
195 hir::ItemKind::Static(ident, ty, *m, body_id)
196 }
197 ItemKind::Const(box ast::ConstItem {
198 ident,
199 generics,
200 ty,
201 expr,
202 define_opaque,
203 ..
204 }) => {
205 let ident = self.lower_ident(*ident);
206 let (generics, (ty, body_id)) = self.lower_generics(
207 generics,
208 id,
209 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
210 |this| {
211 this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
212 },
213 );
214 self.lower_define_opaque(hir_id, &define_opaque);
215 hir::ItemKind::Const(ident, ty, generics, body_id)
216 }
217 ItemKind::Fn(box Fn {
218 sig: FnSig { decl, header, span: fn_sig_span },
219 ident,
220 generics,
221 body,
222 contract,
223 define_opaque,
224 ..
225 }) => {
226 self.with_new_scopes(*fn_sig_span, |this| {
227 let coroutine_kind = header.coroutine_kind;
232 let body_id = this.lower_maybe_coroutine_body(
233 *fn_sig_span,
234 span,
235 hir_id,
236 decl,
237 coroutine_kind,
238 body.as_deref(),
239 attrs,
240 contract.as_deref(),
241 );
242
243 let itctx = ImplTraitContext::Universal;
244 let (generics, decl) = this.lower_generics(generics, id, itctx, |this| {
245 this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coroutine_kind)
246 });
247 let sig = hir::FnSig {
248 decl,
249 header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
250 span: this.lower_span(*fn_sig_span),
251 };
252 this.lower_define_opaque(hir_id, define_opaque);
253 let ident = this.lower_ident(*ident);
254 hir::ItemKind::Fn {
255 ident,
256 sig,
257 generics,
258 body: body_id,
259 has_body: body.is_some(),
260 }
261 })
262 }
263 ItemKind::Mod(_, ident, mod_kind) => {
264 let ident = self.lower_ident(*ident);
265 match mod_kind {
266 ModKind::Loaded(items, _, spans, _) => {
267 hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
268 }
269 ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
270 }
271 }
272 ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod {
273 abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
274 items: self
275 .arena
276 .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
277 },
278 ItemKind::GlobalAsm(asm) => {
279 let asm = self.lower_inline_asm(span, asm);
280 let fake_body =
281 self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
282 hir::ItemKind::GlobalAsm { asm, fake_body }
283 }
284 ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
285 let ident = self.lower_ident(*ident);
294 let mut generics = generics.clone();
295 add_ty_alias_where_clause(&mut generics, *where_clauses, true);
296 let (generics, ty) = self.lower_generics(
297 &generics,
298 id,
299 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
300 |this| match ty {
301 None => {
302 let guar = this.dcx().span_delayed_bug(
303 span,
304 "expected to lower type alias type, but it was missing",
305 );
306 this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
307 }
308 Some(ty) => this.lower_ty(
309 ty,
310 ImplTraitContext::OpaqueTy {
311 origin: hir::OpaqueTyOrigin::TyAlias {
312 parent: this.local_def_id(id),
313 in_assoc_ty: false,
314 },
315 },
316 ),
317 },
318 );
319 hir::ItemKind::TyAlias(ident, ty, generics)
320 }
321 ItemKind::Enum(ident, enum_definition, generics) => {
322 let ident = self.lower_ident(*ident);
323 let (generics, variants) = self.lower_generics(
324 generics,
325 id,
326 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
327 |this| {
328 this.arena.alloc_from_iter(
329 enum_definition.variants.iter().map(|x| this.lower_variant(x)),
330 )
331 },
332 );
333 hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
334 }
335 ItemKind::Struct(ident, struct_def, generics) => {
336 let ident = self.lower_ident(*ident);
337 let (generics, struct_def) = self.lower_generics(
338 generics,
339 id,
340 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
341 |this| this.lower_variant_data(hir_id, struct_def),
342 );
343 hir::ItemKind::Struct(ident, struct_def, generics)
344 }
345 ItemKind::Union(ident, vdata, generics) => {
346 let ident = self.lower_ident(*ident);
347 let (generics, vdata) = self.lower_generics(
348 generics,
349 id,
350 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
351 |this| this.lower_variant_data(hir_id, vdata),
352 );
353 hir::ItemKind::Union(ident, vdata, generics)
354 }
355 ItemKind::Impl(box Impl {
356 safety,
357 polarity,
358 defaultness,
359 constness,
360 generics: ast_generics,
361 of_trait: trait_ref,
362 self_ty: ty,
363 items: impl_items,
364 }) => {
365 let itctx = ImplTraitContext::Universal;
379 let (generics, (trait_ref, lowered_ty)) =
380 self.lower_generics(ast_generics, id, itctx, |this| {
381 let modifiers = TraitBoundModifiers {
382 constness: BoundConstness::Never,
383 asyncness: BoundAsyncness::Normal,
384 polarity: BoundPolarity::Positive,
386 };
387
388 let trait_ref = trait_ref.as_ref().map(|trait_ref| {
389 this.lower_trait_ref(
390 modifiers,
391 trait_ref,
392 ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
393 )
394 });
395
396 let lowered_ty = this.lower_ty(
397 ty,
398 ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
399 );
400
401 (trait_ref, lowered_ty)
402 });
403
404 let new_impl_items = self.arena.alloc_from_iter(
405 impl_items
406 .iter()
407 .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
408 );
409
410 let has_val = true;
413 let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val);
414 let polarity = match polarity {
415 ImplPolarity::Positive => ImplPolarity::Positive,
416 ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
417 };
418 hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
419 constness: self.lower_constness(*constness),
420 safety: self.lower_safety(*safety, hir::Safety::Safe),
421 polarity,
422 defaultness,
423 defaultness_span,
424 generics,
425 of_trait: trait_ref,
426 self_ty: lowered_ty,
427 items: new_impl_items,
428 }))
429 }
430 ItemKind::Trait(box Trait { is_auto, safety, ident, generics, bounds, items }) => {
431 let ident = self.lower_ident(*ident);
432 let (generics, (safety, items, bounds)) = self.lower_generics(
433 generics,
434 id,
435 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
436 |this| {
437 let bounds = this.lower_param_bounds(
438 bounds,
439 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
440 );
441 let items = this.arena.alloc_from_iter(
442 items.iter().map(|item| this.lower_trait_item_ref(item)),
443 );
444 let safety = this.lower_safety(*safety, hir::Safety::Safe);
445 (safety, items, bounds)
446 },
447 );
448 hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
449 }
450 ItemKind::TraitAlias(ident, generics, bounds) => {
451 let ident = self.lower_ident(*ident);
452 let (generics, bounds) = self.lower_generics(
453 generics,
454 id,
455 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
456 |this| {
457 this.lower_param_bounds(
458 bounds,
459 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
460 )
461 },
462 );
463 hir::ItemKind::TraitAlias(ident, generics, bounds)
464 }
465 ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
466 let ident = self.lower_ident(*ident);
467 let body = P(self.lower_delim_args(body));
468 let def_id = self.local_def_id(id);
469 let def_kind = self.tcx.def_kind(def_id);
470 let DefKind::Macro(macro_kind) = def_kind else {
471 unreachable!(
472 "expected DefKind::Macro for macro item, found {}",
473 def_kind.descr(def_id.to_def_id())
474 );
475 };
476 let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
477 hir::ItemKind::Macro(ident, macro_def, macro_kind)
478 }
479 ItemKind::Delegation(box delegation) => {
480 let delegation_results = self.lower_delegation(delegation, id, false);
481 hir::ItemKind::Fn {
482 ident: delegation_results.ident,
483 sig: delegation_results.sig,
484 generics: delegation_results.generics,
485 body: delegation_results.body_id,
486 has_body: true,
487 }
488 }
489 ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
490 panic!("macros should have been expanded by now")
491 }
492 }
493 }
494
495 fn lower_const_item(
496 &mut self,
497 ty: &Ty,
498 span: Span,
499 body: Option<&Expr>,
500 impl_trait_position: ImplTraitPosition,
501 ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
502 let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
503 (ty, self.lower_const_body(span, body))
504 }
505
506 #[instrument(level = "debug", skip(self))]
507 fn lower_use_tree(
508 &mut self,
509 tree: &UseTree,
510 prefix: &Path,
511 id: NodeId,
512 vis_span: Span,
513 attrs: &'hir [hir::Attribute],
514 ) -> hir::ItemKind<'hir> {
515 let path = &tree.prefix;
516 let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
517
518 match tree.kind {
519 UseTreeKind::Simple(rename) => {
520 let mut ident = tree.ident();
521
522 let mut path = Path { segments, span: path.span, tokens: None };
524
525 if path.segments.len() > 1
527 && path.segments.last().unwrap().ident.name == kw::SelfLower
528 {
529 let _ = path.segments.pop();
530 if rename.is_none() {
531 ident = path.segments.last().unwrap().ident;
532 }
533 }
534
535 let res = self.lower_import_res(id, path.span);
536 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
537 let ident = self.lower_ident(ident);
538 hir::ItemKind::Use(path, hir::UseKind::Single(ident))
539 }
540 UseTreeKind::Glob => {
541 let res = self.expect_full_res(id);
542 let res = smallvec![self.lower_res(res)];
543 let path = Path { segments, span: path.span, tokens: None };
544 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
545 hir::ItemKind::Use(path, hir::UseKind::Glob)
546 }
547 UseTreeKind::Nested { items: ref trees, .. } => {
548 let span = prefix.span.to(path.span);
573 let prefix = Path { segments, span, tokens: None };
574
575 for &(ref use_tree, id) in trees {
577 let owner_id = self.owner_id(id);
578
579 self.with_hir_id_owner(id, |this| {
585 let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
589 if !attrs.is_empty() {
590 this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
591 }
592
593 let item = hir::Item {
594 owner_id,
595 kind,
596 vis_span,
597 span: this.lower_span(use_tree.span),
598 };
599 hir::OwnerNode::Item(this.arena.alloc(item))
600 });
601 }
602
603 let path = if trees.is_empty()
605 && !(prefix.segments.is_empty()
606 || prefix.segments.len() == 1
607 && prefix.segments[0].ident.name == kw::PathRoot)
608 {
609 let res = self.lower_import_res(id, span);
612 self.lower_use_path(res, &prefix, ParamMode::Explicit)
613 } else {
614 self.arena.alloc(hir::UsePath { res: smallvec![], segments: &[], span })
617 };
618 hir::ItemKind::Use(path, hir::UseKind::ListStem)
619 }
620 }
621 }
622
623 fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
624 match ctxt {
628 AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
629 AssocCtxt::Impl { of_trait } => {
630 hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
631 }
632 }
633 }
634
635 fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
636 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
637 let owner_id = hir_id.expect_owner();
638 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
639 let (ident, kind) = match &i.kind {
640 ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
641 let fdec = &sig.decl;
642 let itctx = ImplTraitContext::Universal;
643 let (generics, (decl, fn_args)) =
644 self.lower_generics(generics, i.id, itctx, |this| {
645 (
646 this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
648 this.lower_fn_params_to_idents(fdec),
649 )
650 });
651
652 let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
654
655 if define_opaque.is_some() {
656 self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
657 }
658
659 (
660 ident,
661 hir::ForeignItemKind::Fn(
662 hir::FnSig { header, decl, span: self.lower_span(sig.span) },
663 fn_args,
664 generics,
665 ),
666 )
667 }
668 ForeignItemKind::Static(box StaticItem {
669 ident,
670 ty,
671 mutability,
672 expr: _,
673 safety,
674 define_opaque,
675 }) => {
676 let ty =
677 self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
678 let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
679 if define_opaque.is_some() {
680 self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
681 }
682 (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
683 }
684 ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
685 (ident, hir::ForeignItemKind::Type)
686 }
687 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
688 };
689
690 let item = hir::ForeignItem {
691 owner_id,
692 ident: self.lower_ident(*ident),
693 kind,
694 vis_span: self.lower_span(i.vis.span),
695 span: self.lower_span(i.span),
696 };
697 self.arena.alloc(item)
698 }
699
700 fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
701 hir::ForeignItemRef {
702 id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
703 ident: self.lower_ident(i.kind.ident().unwrap()),
706 span: self.lower_span(i.span),
707 }
708 }
709
710 fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
711 let hir_id = self.lower_node_id(v.id);
712 self.lower_attrs(hir_id, &v.attrs, v.span);
713 hir::Variant {
714 hir_id,
715 def_id: self.local_def_id(v.id),
716 data: self.lower_variant_data(hir_id, &v.data),
717 disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
718 ident: self.lower_ident(v.ident),
719 span: self.lower_span(v.span),
720 }
721 }
722
723 fn lower_variant_data(
724 &mut self,
725 parent_id: hir::HirId,
726 vdata: &VariantData,
727 ) -> hir::VariantData<'hir> {
728 match vdata {
729 VariantData::Struct { fields, recovered } => hir::VariantData::Struct {
730 fields: self
731 .arena
732 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
733 recovered: *recovered,
734 },
735 VariantData::Tuple(fields, id) => {
736 let ctor_id = self.lower_node_id(*id);
737 self.alias_attrs(ctor_id, parent_id);
738 let fields = self
739 .arena
740 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
741 for field in &fields[..] {
742 if let Some(default) = field.default {
743 if self.tcx.features().default_field_values() {
748 self.dcx().emit_err(TupleStructWithDefault { span: default.span });
749 } else {
750 let _ = self.dcx().span_delayed_bug(
751 default.span,
752 "expected `default values on `struct` fields aren't supported` \
753 feature-gate error but none was produced",
754 );
755 }
756 }
757 }
758 hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))
759 }
760 VariantData::Unit(id) => {
761 let ctor_id = self.lower_node_id(*id);
762 self.alias_attrs(ctor_id, parent_id);
763 hir::VariantData::Unit(ctor_id, self.local_def_id(*id))
764 }
765 }
766 }
767
768 pub(super) fn lower_field_def(
769 &mut self,
770 (index, f): (usize, &FieldDef),
771 ) -> hir::FieldDef<'hir> {
772 let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
773 let hir_id = self.lower_node_id(f.id);
774 self.lower_attrs(hir_id, &f.attrs, f.span);
775 hir::FieldDef {
776 span: self.lower_span(f.span),
777 hir_id,
778 def_id: self.local_def_id(f.id),
779 ident: match f.ident {
780 Some(ident) => self.lower_ident(ident),
781 None => Ident::new(sym::integer(index), self.lower_span(f.span)),
783 },
784 vis_span: self.lower_span(f.vis.span),
785 default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
786 ty,
787 safety: self.lower_safety(f.safety, hir::Safety::Safe),
788 }
789 }
790
791 fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
792 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
793 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
794 let trait_item_def_id = hir_id.expect_owner();
795
796 let (ident, generics, kind, has_default) = match &i.kind {
797 AssocItemKind::Const(box ConstItem {
798 ident,
799 generics,
800 ty,
801 expr,
802 define_opaque,
803 ..
804 }) => {
805 let (generics, kind) = self.lower_generics(
806 generics,
807 i.id,
808 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
809 |this| {
810 let ty = this
811 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
812 let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
813
814 hir::TraitItemKind::Const(ty, body)
815 },
816 );
817
818 if define_opaque.is_some() {
819 if expr.is_some() {
820 self.lower_define_opaque(hir_id, &define_opaque);
821 } else {
822 self.dcx().span_err(
823 i.span,
824 "only trait consts with default bodies can define opaque types",
825 );
826 }
827 }
828
829 (*ident, generics, kind, expr.is_some())
830 }
831 AssocItemKind::Fn(box Fn {
832 sig, ident, generics, body: None, define_opaque, ..
833 }) => {
834 let idents = self.lower_fn_params_to_idents(&sig.decl);
837 let (generics, sig) = self.lower_method_sig(
838 generics,
839 sig,
840 i.id,
841 FnDeclKind::Trait,
842 sig.header.coroutine_kind,
843 attrs,
844 );
845 if define_opaque.is_some() {
846 self.dcx().span_err(
847 i.span,
848 "only trait methods with default bodies can define opaque types",
849 );
850 }
851 (
852 *ident,
853 generics,
854 hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),
855 false,
856 )
857 }
858 AssocItemKind::Fn(box Fn {
859 sig,
860 ident,
861 generics,
862 body: Some(body),
863 contract,
864 define_opaque,
865 ..
866 }) => {
867 let body_id = self.lower_maybe_coroutine_body(
868 sig.span,
869 i.span,
870 hir_id,
871 &sig.decl,
872 sig.header.coroutine_kind,
873 Some(body),
874 attrs,
875 contract.as_deref(),
876 );
877 let (generics, sig) = self.lower_method_sig(
878 generics,
879 sig,
880 i.id,
881 FnDeclKind::Trait,
882 sig.header.coroutine_kind,
883 attrs,
884 );
885 self.lower_define_opaque(hir_id, &define_opaque);
886 (
887 *ident,
888 generics,
889 hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
890 true,
891 )
892 }
893 AssocItemKind::Type(box TyAlias {
894 ident, generics, where_clauses, bounds, ty, ..
895 }) => {
896 let mut generics = generics.clone();
897 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
898 let (generics, kind) = self.lower_generics(
899 &generics,
900 i.id,
901 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
902 |this| {
903 let ty = ty.as_ref().map(|x| {
904 this.lower_ty(
905 x,
906 ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
907 )
908 });
909 hir::TraitItemKind::Type(
910 this.lower_param_bounds(
911 bounds,
912 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
913 ),
914 ty,
915 )
916 },
917 );
918 (*ident, generics, kind, ty.is_some())
919 }
920 AssocItemKind::Delegation(box delegation) => {
921 let delegation_results = self.lower_delegation(delegation, i.id, false);
922 let item_kind = hir::TraitItemKind::Fn(
923 delegation_results.sig,
924 hir::TraitFn::Provided(delegation_results.body_id),
925 );
926 (delegation.ident, delegation_results.generics, item_kind, true)
927 }
928 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
929 panic!("macros should have been expanded by now")
930 }
931 };
932
933 let item = hir::TraitItem {
934 owner_id: trait_item_def_id,
935 ident: self.lower_ident(ident),
936 generics,
937 kind,
938 span: self.lower_span(i.span),
939 defaultness: hir::Defaultness::Default { has_value: has_default },
940 };
941 self.arena.alloc(item)
942 }
943
944 fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
945 let (ident, kind) = match &i.kind {
946 AssocItemKind::Const(box ConstItem { ident, .. }) => {
947 (*ident, hir::AssocItemKind::Const)
948 }
949 AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
950 AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
951 (*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
952 }
953 AssocItemKind::Delegation(box delegation) => (
954 delegation.ident,
955 hir::AssocItemKind::Fn {
956 has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
957 },
958 ),
959 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
960 panic!("macros should have been expanded by now")
961 }
962 };
963 let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
964 hir::TraitItemRef {
965 id,
966 ident: self.lower_ident(ident),
967 span: self.lower_span(i.span),
968 kind,
969 }
970 }
971
972 pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {
974 self.expr(span, hir::ExprKind::Err(guar))
975 }
976
977 fn lower_impl_item(
978 &mut self,
979 i: &AssocItem,
980 is_in_trait_impl: bool,
981 ) -> &'hir hir::ImplItem<'hir> {
982 let has_value = true;
984 let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
985 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
986 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
987
988 let (ident, (generics, kind)) = match &i.kind {
989 AssocItemKind::Const(box ConstItem {
990 ident,
991 generics,
992 ty,
993 expr,
994 define_opaque,
995 ..
996 }) => (
997 *ident,
998 self.lower_generics(
999 generics,
1000 i.id,
1001 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1002 |this| {
1003 let ty = this
1004 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1005 let body = this.lower_const_body(i.span, expr.as_deref());
1006 this.lower_define_opaque(hir_id, &define_opaque);
1007 hir::ImplItemKind::Const(ty, body)
1008 },
1009 ),
1010 ),
1011 AssocItemKind::Fn(box Fn {
1012 sig,
1013 ident,
1014 generics,
1015 body,
1016 contract,
1017 define_opaque,
1018 ..
1019 }) => {
1020 let body_id = self.lower_maybe_coroutine_body(
1021 sig.span,
1022 i.span,
1023 hir_id,
1024 &sig.decl,
1025 sig.header.coroutine_kind,
1026 body.as_deref(),
1027 attrs,
1028 contract.as_deref(),
1029 );
1030 let (generics, sig) = self.lower_method_sig(
1031 generics,
1032 sig,
1033 i.id,
1034 if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
1035 sig.header.coroutine_kind,
1036 attrs,
1037 );
1038 self.lower_define_opaque(hir_id, &define_opaque);
1039
1040 (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
1041 }
1042 AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
1043 let mut generics = generics.clone();
1044 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
1045 (
1046 *ident,
1047 self.lower_generics(
1048 &generics,
1049 i.id,
1050 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1051 |this| match ty {
1052 None => {
1053 let guar = this.dcx().span_delayed_bug(
1054 i.span,
1055 "expected to lower associated type, but it was missing",
1056 );
1057 let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
1058 hir::ImplItemKind::Type(ty)
1059 }
1060 Some(ty) => {
1061 let ty = this.lower_ty(
1062 ty,
1063 ImplTraitContext::OpaqueTy {
1064 origin: hir::OpaqueTyOrigin::TyAlias {
1065 parent: this.local_def_id(i.id),
1066 in_assoc_ty: true,
1067 },
1068 },
1069 );
1070 hir::ImplItemKind::Type(ty)
1071 }
1072 },
1073 ),
1074 )
1075 }
1076 AssocItemKind::Delegation(box delegation) => {
1077 let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
1078 (
1079 delegation.ident,
1080 (
1081 delegation_results.generics,
1082 hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
1083 ),
1084 )
1085 }
1086 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1087 panic!("macros should have been expanded by now")
1088 }
1089 };
1090
1091 let item = hir::ImplItem {
1092 owner_id: hir_id.expect_owner(),
1093 ident: self.lower_ident(ident),
1094 generics,
1095 kind,
1096 vis_span: self.lower_span(i.vis.span),
1097 span: self.lower_span(i.span),
1098 defaultness,
1099 };
1100 self.arena.alloc(item)
1101 }
1102
1103 fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
1104 hir::ImplItemRef {
1105 id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
1106 ident: self.lower_ident(i.kind.ident().unwrap()),
1109 span: self.lower_span(i.span),
1110 kind: match &i.kind {
1111 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
1112 AssocItemKind::Type(..) => hir::AssocItemKind::Type,
1113 AssocItemKind::Fn(box Fn { sig, .. }) => {
1114 hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
1115 }
1116 AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
1117 has_self: self.delegatee_is_method(
1118 i.id,
1119 delegation.id,
1120 i.span,
1121 is_in_trait_impl,
1122 ),
1123 },
1124 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1125 panic!("macros should have been expanded by now")
1126 }
1127 },
1128 trait_item_def_id: self
1129 .resolver
1130 .get_partial_res(i.id)
1131 .map(|r| r.expect_full_res().opt_def_id())
1132 .unwrap_or(None),
1133 }
1134 }
1135
1136 fn lower_defaultness(
1137 &self,
1138 d: Defaultness,
1139 has_value: bool,
1140 ) -> (hir::Defaultness, Option<Span>) {
1141 match d {
1142 Defaultness::Default(sp) => {
1143 (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
1144 }
1145 Defaultness::Final => {
1146 assert!(has_value);
1147 (hir::Defaultness::Final, None)
1148 }
1149 }
1150 }
1151
1152 fn record_body(
1153 &mut self,
1154 params: &'hir [hir::Param<'hir>],
1155 value: hir::Expr<'hir>,
1156 ) -> hir::BodyId {
1157 let body = hir::Body { params, value: self.arena.alloc(value) };
1158 let id = body.id();
1159 debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
1160 self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
1161 id
1162 }
1163
1164 pub(super) fn lower_body(
1165 &mut self,
1166 f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
1167 ) -> hir::BodyId {
1168 let prev_coroutine_kind = self.coroutine_kind.take();
1169 let task_context = self.task_context.take();
1170 let (parameters, result) = f(self);
1171 let body_id = self.record_body(parameters, result);
1172 self.task_context = task_context;
1173 self.coroutine_kind = prev_coroutine_kind;
1174 body_id
1175 }
1176
1177 fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1178 let hir_id = self.lower_node_id(param.id);
1179 self.lower_attrs(hir_id, ¶m.attrs, param.span);
1180 hir::Param {
1181 hir_id,
1182 pat: self.lower_pat(¶m.pat),
1183 ty_span: self.lower_span(param.ty.span),
1184 span: self.lower_span(param.span),
1185 }
1186 }
1187
1188 pub(super) fn lower_fn_body(
1189 &mut self,
1190 decl: &FnDecl,
1191 contract: Option<&FnContract>,
1192 body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
1193 ) -> hir::BodyId {
1194 self.lower_body(|this| {
1195 let params =
1196 this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
1197
1198 if let Some(contract) = contract {
1206 let precond = if let Some(req) = &contract.requires {
1207 let lowered_req = this.lower_expr_mut(&req);
1209 let req_span = this.mark_span_with_reason(
1210 DesugaringKind::Contract,
1211 lowered_req.span,
1212 None,
1213 );
1214 let precond = this.expr_call_lang_item_fn_mut(
1215 req_span,
1216 hir::LangItem::ContractCheckRequires,
1217 &*arena_vec![this; lowered_req],
1218 );
1219 Some(this.stmt_expr(req.span, precond))
1220 } else {
1221 None
1222 };
1223 let (postcond, body) = if let Some(ens) = &contract.ensures {
1224 let ens_span = this.lower_span(ens.span);
1225 let ens_span =
1226 this.mark_span_with_reason(DesugaringKind::Contract, ens_span, None);
1227 let check_ident: Ident =
1229 Ident::from_str_and_span("__ensures_checker", ens_span);
1230 let (checker_pat, check_hir_id) = this.pat_ident_binding_mode_mut(
1231 ens_span,
1232 check_ident,
1233 hir::BindingMode::NONE,
1234 );
1235 let lowered_ens = this.lower_expr_mut(&ens);
1236 let postcond_checker = this.expr_call_lang_item_fn(
1237 ens_span,
1238 hir::LangItem::ContractBuildCheckEnsures,
1239 &*arena_vec![this; lowered_ens],
1240 );
1241 let postcond = this.stmt_let_pat(
1242 None,
1243 ens_span,
1244 Some(postcond_checker),
1245 this.arena.alloc(checker_pat),
1246 hir::LocalSource::Contract,
1247 );
1248
1249 this.contract_ensures = Some((ens_span, check_ident, check_hir_id));
1252 let body = this.arena.alloc(body(this));
1253
1254 let body = this.inject_ensures_check(body, ens_span, check_ident, check_hir_id);
1256 (Some(postcond), body)
1257 } else {
1258 let body = &*this.arena.alloc(body(this));
1259 (None, body)
1260 };
1261 let wrapped_body = this.block_all(
1263 body.span,
1264 this.arena.alloc_from_iter([precond, postcond].into_iter().flatten()),
1265 Some(body),
1266 );
1267 (params, this.expr_block(wrapped_body))
1268 } else {
1269 (params, body(this))
1270 }
1271 })
1272 }
1273
1274 fn lower_fn_body_block(
1275 &mut self,
1276 decl: &FnDecl,
1277 body: &Block,
1278 contract: Option<&FnContract>,
1279 ) -> hir::BodyId {
1280 self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
1281 }
1282
1283 pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1284 self.lower_body(|this| {
1285 (
1286 &[],
1287 match expr {
1288 Some(expr) => this.lower_expr_mut(expr),
1289 None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
1290 },
1291 )
1292 })
1293 }
1294
1295 fn lower_maybe_coroutine_body(
1298 &mut self,
1299 fn_decl_span: Span,
1300 span: Span,
1301 fn_id: hir::HirId,
1302 decl: &FnDecl,
1303 coroutine_kind: Option<CoroutineKind>,
1304 body: Option<&Block>,
1305 attrs: &'hir [hir::Attribute],
1306 contract: Option<&FnContract>,
1307 ) -> hir::BodyId {
1308 let Some(body) = body else {
1309 return self.lower_fn_body(decl, contract, |this| {
1313 if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
1314 || this.tcx.is_sdylib_interface_build()
1315 {
1316 let span = this.lower_span(span);
1317 let empty_block = hir::Block {
1318 hir_id: this.next_id(),
1319 stmts: &[],
1320 expr: None,
1321 rules: hir::BlockCheckMode::DefaultBlock,
1322 span,
1323 targeted_by_break: false,
1324 };
1325 let loop_ = hir::ExprKind::Loop(
1326 this.arena.alloc(empty_block),
1327 None,
1328 hir::LoopSource::Loop,
1329 span,
1330 );
1331 hir::Expr { hir_id: this.next_id(), kind: loop_, span }
1332 } else {
1333 this.expr_err(span, this.dcx().has_errors().unwrap())
1334 }
1335 });
1336 };
1337 let Some(coroutine_kind) = coroutine_kind else {
1338 return self.lower_fn_body_block(decl, body, contract);
1340 };
1341 self.lower_body(|this| {
1343 let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1344 decl,
1345 |this| this.lower_block_expr(body),
1346 fn_decl_span,
1347 body.span,
1348 coroutine_kind,
1349 hir::CoroutineSource::Fn,
1350 );
1351
1352 let hir_id = expr.hir_id;
1354 this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1355
1356 (parameters, expr)
1357 })
1358 }
1359
1360 pub(crate) fn lower_coroutine_body_with_moved_arguments(
1365 &mut self,
1366 decl: &FnDecl,
1367 lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
1368 fn_decl_span: Span,
1369 body_span: Span,
1370 coroutine_kind: CoroutineKind,
1371 coroutine_source: hir::CoroutineSource,
1372 ) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {
1373 let mut parameters: Vec<hir::Param<'_>> = Vec::new();
1374 let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
1375
1376 for (index, parameter) in decl.inputs.iter().enumerate() {
1409 let parameter = self.lower_param(parameter);
1410 let span = parameter.pat.span;
1411
1412 let (ident, is_simple_parameter) = match parameter.pat.kind {
1415 hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),
1416 hir::PatKind::Binding(_, _, ident, _) => (ident, false),
1420 hir::PatKind::Wild => (Ident::with_dummy_span(rustc_span::kw::Underscore), false),
1421 _ => {
1422 let name = format!("__arg{index}");
1424 let ident = Ident::from_str(&name);
1425
1426 (ident, false)
1427 }
1428 };
1429
1430 let desugared_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1431
1432 let stmt_attrs = self.attrs.get(¶meter.hir_id.local_id).copied();
1438 let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident);
1439 let new_parameter = hir::Param {
1440 hir_id: parameter.hir_id,
1441 pat: new_parameter_pat,
1442 ty_span: self.lower_span(parameter.ty_span),
1443 span: self.lower_span(parameter.span),
1444 };
1445
1446 if is_simple_parameter {
1447 let expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1451 let stmt = self.stmt_let_pat(
1452 stmt_attrs,
1453 desugared_span,
1454 Some(expr),
1455 parameter.pat,
1456 hir::LocalSource::AsyncFn,
1457 );
1458 statements.push(stmt);
1459 } else {
1460 let (move_pat, move_id) =
1476 self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);
1477 let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1478 let move_stmt = self.stmt_let_pat(
1479 None,
1480 desugared_span,
1481 Some(move_expr),
1482 move_pat,
1483 hir::LocalSource::AsyncFn,
1484 );
1485
1486 let pattern_expr = self.expr_ident(desugared_span, ident, move_id);
1489 let pattern_stmt = self.stmt_let_pat(
1490 stmt_attrs,
1491 desugared_span,
1492 Some(pattern_expr),
1493 parameter.pat,
1494 hir::LocalSource::AsyncFn,
1495 );
1496
1497 statements.push(move_stmt);
1498 statements.push(pattern_stmt);
1499 };
1500
1501 parameters.push(new_parameter);
1502 }
1503
1504 let mkbody = |this: &mut LoweringContext<'_, 'hir>| {
1505 let user_body = lower_body(this);
1507
1508 let desugared_span =
1510 this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
1511 let user_body = this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
1512
1513 let body = this.block_all(
1523 desugared_span,
1524 this.arena.alloc_from_iter(statements),
1525 Some(user_body),
1526 );
1527
1528 this.expr_block(body)
1529 };
1530 let desugaring_kind = match coroutine_kind {
1531 CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,
1532 CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,
1533 CoroutineKind::AsyncGen { .. } => hir::CoroutineDesugaring::AsyncGen,
1534 };
1535 let closure_id = coroutine_kind.closure_id();
1536
1537 let coroutine_expr = self.make_desugared_coroutine_expr(
1538 CaptureBy::Ref,
1543 closure_id,
1544 None,
1545 fn_decl_span,
1546 body_span,
1547 desugaring_kind,
1548 coroutine_source,
1549 mkbody,
1550 );
1551
1552 let expr = hir::Expr {
1553 hir_id: self.lower_node_id(closure_id),
1554 kind: coroutine_expr,
1555 span: self.lower_span(body_span),
1556 };
1557
1558 (self.arena.alloc_from_iter(parameters), expr)
1559 }
1560
1561 fn lower_method_sig(
1562 &mut self,
1563 generics: &Generics,
1564 sig: &FnSig,
1565 id: NodeId,
1566 kind: FnDeclKind,
1567 coroutine_kind: Option<CoroutineKind>,
1568 attrs: &[hir::Attribute],
1569 ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
1570 let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
1571 let itctx = ImplTraitContext::Universal;
1572 let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1573 this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1574 });
1575 (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
1576 }
1577
1578 pub(super) fn lower_fn_header(
1579 &mut self,
1580 h: FnHeader,
1581 default_safety: hir::Safety,
1582 attrs: &[hir::Attribute],
1583 ) -> hir::FnHeader {
1584 let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
1585 hir::IsAsync::Async(span)
1586 } else {
1587 hir::IsAsync::NotAsync
1588 };
1589
1590 let safety = self.lower_safety(h.safety, default_safety);
1591
1592 let safety = if attrs.iter().any(|attr| attr.has_name(sym::target_feature))
1594 && safety.is_safe()
1595 && !self.tcx.sess.target.is_like_wasm
1596 {
1597 hir::HeaderSafety::SafeTargetFeatures
1598 } else {
1599 safety.into()
1600 };
1601
1602 hir::FnHeader {
1603 safety,
1604 asyncness,
1605 constness: self.lower_constness(h.constness),
1606 abi: self.lower_extern(h.ext),
1607 }
1608 }
1609
1610 pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {
1611 let ast::StrLit { symbol_unescaped, span, .. } = abi_str;
1612 let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| {
1613 self.error_on_invalid_abi(abi_str);
1614 ExternAbi::Rust
1615 });
1616 let sess = self.tcx.sess;
1617 let features = self.tcx.features();
1618 gate_unstable_abi(sess, features, span, extern_abi);
1619 extern_abi
1620 }
1621
1622 pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {
1623 match ext {
1624 Extern::None => ExternAbi::Rust,
1625 Extern::Implicit(_) => ExternAbi::FALLBACK,
1626 Extern::Explicit(abi, _) => self.lower_abi(abi),
1627 }
1628 }
1629
1630 fn error_on_invalid_abi(&self, abi: StrLit) {
1631 let abi_names = enabled_names(self.tcx.features(), abi.span)
1632 .iter()
1633 .map(|s| Symbol::intern(s))
1634 .collect::<Vec<_>>();
1635 let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
1636 self.dcx().emit_err(InvalidAbi {
1637 abi: abi.symbol_unescaped,
1638 span: abi.span,
1639 suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
1640 span: abi.span,
1641 suggestion: suggested_name.to_string(),
1642 }),
1643 command: "rustc --print=calling-conventions".to_string(),
1644 });
1645 }
1646
1647 pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
1648 match c {
1649 Const::Yes(_) => hir::Constness::Const,
1650 Const::No => hir::Constness::NotConst,
1651 }
1652 }
1653
1654 pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {
1655 match s {
1656 Safety::Unsafe(_) => hir::Safety::Unsafe,
1657 Safety::Default => default,
1658 Safety::Safe(_) => hir::Safety::Safe,
1659 }
1660 }
1661
1662 #[instrument(level = "debug", skip(self, f))]
1665 fn lower_generics<T>(
1666 &mut self,
1667 generics: &Generics,
1668 parent_node_id: NodeId,
1669 itctx: ImplTraitContext,
1670 f: impl FnOnce(&mut Self) -> T,
1671 ) -> (&'hir hir::Generics<'hir>, T) {
1672 debug_assert!(self.impl_trait_defs.is_empty());
1673 debug_assert!(self.impl_trait_bounds.is_empty());
1674
1675 for pred in &generics.where_clause.predicates {
1681 let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else {
1682 continue;
1683 };
1684 let compute_is_param = || {
1685 match self
1687 .resolver
1688 .get_partial_res(bound_pred.bounded_ty.id)
1689 .and_then(|r| r.full_res())
1690 {
1691 Some(Res::Def(DefKind::TyParam, def_id))
1692 if bound_pred.bound_generic_params.is_empty() =>
1693 {
1694 generics
1695 .params
1696 .iter()
1697 .any(|p| def_id == self.local_def_id(p.id).to_def_id())
1698 }
1699 _ => false,
1702 }
1703 };
1704 let mut is_param: Option<bool> = None;
1707 for bound in &bound_pred.bounds {
1708 if !matches!(
1709 *bound,
1710 GenericBound::Trait(PolyTraitRef {
1711 modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
1712 ..
1713 })
1714 ) {
1715 continue;
1716 }
1717 let is_param = *is_param.get_or_insert_with(compute_is_param);
1718 if !is_param && !self.tcx.features().more_maybe_bounds() {
1719 self.tcx
1720 .sess
1721 .create_feature_err(
1722 MisplacedRelaxTraitBound { span: bound.span() },
1723 sym::more_maybe_bounds,
1724 )
1725 .emit();
1726 }
1727 }
1728 }
1729
1730 let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
1731 predicates.extend(generics.params.iter().filter_map(|param| {
1732 self.lower_generic_bound_predicate(
1733 param.ident,
1734 param.id,
1735 ¶m.kind,
1736 ¶m.bounds,
1737 param.colon_span,
1738 generics.span,
1739 itctx,
1740 PredicateOrigin::GenericParam,
1741 )
1742 }));
1743 predicates.extend(
1744 generics
1745 .where_clause
1746 .predicates
1747 .iter()
1748 .map(|predicate| self.lower_where_predicate(predicate)),
1749 );
1750
1751 let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self
1752 .lower_generic_params_mut(&generics.params, hir::GenericParamSource::Generics)
1753 .collect();
1754
1755 let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);
1757 params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
1758 self.lifetime_res_to_generic_param(
1759 ident,
1760 node_id,
1761 res,
1762 hir::GenericParamSource::Generics,
1763 )
1764 }));
1765
1766 let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();
1767 let where_clause_span = self.lower_span(generics.where_clause.span);
1768 let span = self.lower_span(generics.span);
1769 let res = f(self);
1770
1771 let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
1772 params.extend(impl_trait_defs.into_iter());
1773
1774 let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
1775 predicates.extend(impl_trait_bounds.into_iter());
1776
1777 let lowered_generics = self.arena.alloc(hir::Generics {
1778 params: self.arena.alloc_from_iter(params),
1779 predicates: self.arena.alloc_from_iter(predicates),
1780 has_where_clause_predicates,
1781 where_clause_span,
1782 span,
1783 });
1784
1785 (lowered_generics, res)
1786 }
1787
1788 pub(super) fn lower_define_opaque(
1789 &mut self,
1790 hir_id: HirId,
1791 define_opaque: &Option<ThinVec<(NodeId, Path)>>,
1792 ) {
1793 assert_eq!(self.define_opaque, None);
1794 assert!(hir_id.is_owner());
1795 let Some(define_opaque) = define_opaque.as_ref() else {
1796 return;
1797 };
1798 let define_opaque = define_opaque.iter().filter_map(|(id, path)| {
1799 let res = self.resolver.get_partial_res(*id);
1800 let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {
1801 self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
1802 return None;
1803 };
1804 let Some(did) = did.as_local() else {
1805 self.dcx().span_err(
1806 path.span,
1807 "only opaque types defined in the local crate can be defined",
1808 );
1809 return None;
1810 };
1811 Some((self.lower_span(path.span), did))
1812 });
1813 let define_opaque = self.arena.alloc_from_iter(define_opaque);
1814 self.define_opaque = Some(define_opaque);
1815 }
1816
1817 pub(super) fn lower_generic_bound_predicate(
1818 &mut self,
1819 ident: Ident,
1820 id: NodeId,
1821 kind: &GenericParamKind,
1822 bounds: &[GenericBound],
1823 colon_span: Option<Span>,
1824 parent_span: Span,
1825 itctx: ImplTraitContext,
1826 origin: PredicateOrigin,
1827 ) -> Option<hir::WherePredicate<'hir>> {
1828 if bounds.is_empty() {
1830 return None;
1831 }
1832
1833 let bounds = self.lower_param_bounds(bounds, itctx);
1834
1835 let param_span = ident.span;
1836
1837 let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());
1839 let span = bounds.iter().fold(span_start, |span_accum, bound| {
1840 match bound.span().find_ancestor_inside(parent_span) {
1841 Some(bound_span) => span_accum.to(bound_span),
1842 None => span_accum,
1843 }
1844 });
1845 let span = self.lower_span(span);
1846 let hir_id = self.next_id();
1847 let kind = self.arena.alloc(match kind {
1848 GenericParamKind::Const { .. } => return None,
1849 GenericParamKind::Type { .. } => {
1850 let def_id = self.local_def_id(id).to_def_id();
1851 let hir_id = self.next_id();
1852 let res = Res::Def(DefKind::TyParam, def_id);
1853 let ident = self.lower_ident(ident);
1854 let ty_path = self.arena.alloc(hir::Path {
1855 span: param_span,
1856 res,
1857 segments: self
1858 .arena
1859 .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
1860 });
1861 let ty_id = self.next_id();
1862 let bounded_ty =
1863 self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
1864 hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1865 bounded_ty: self.arena.alloc(bounded_ty),
1866 bounds,
1867 bound_generic_params: &[],
1868 origin,
1869 })
1870 }
1871 GenericParamKind::Lifetime => {
1872 let lt_id = self.next_node_id();
1873 let lifetime =
1874 self.new_named_lifetime(id, lt_id, ident, LifetimeSource::Other, ident.into());
1875 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1876 lifetime,
1877 bounds,
1878 in_where_clause: false,
1879 })
1880 }
1881 });
1882 Some(hir::WherePredicate { hir_id, span, kind })
1883 }
1884
1885 fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
1886 let hir_id = self.lower_node_id(pred.id);
1887 let span = self.lower_span(pred.span);
1888 self.lower_attrs(hir_id, &pred.attrs, span);
1889 let kind = self.arena.alloc(match &pred.kind {
1890 WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1891 bound_generic_params,
1892 bounded_ty,
1893 bounds,
1894 }) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1895 bound_generic_params: self
1896 .lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
1897 bounded_ty: self
1898 .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1899 bounds: self.lower_param_bounds(
1900 bounds,
1901 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1902 ),
1903 origin: PredicateOrigin::WhereClause,
1904 }),
1905 WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
1906 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1907 lifetime: self.lower_lifetime(
1908 lifetime,
1909 LifetimeSource::Other,
1910 lifetime.ident.into(),
1911 ),
1912 bounds: self.lower_param_bounds(
1913 bounds,
1914 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1915 ),
1916 in_where_clause: true,
1917 })
1918 }
1919 WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
1920 hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
1921 lhs_ty: self
1922 .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1923 rhs_ty: self
1924 .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1925 })
1926 }
1927 });
1928 hir::WherePredicate { hir_id, span, kind }
1929 }
1930}