1use rustc_abi::ExternAbi;
2use rustc_ast::ptr::P;
3use rustc_ast::visit::AssocCtxt;
4use rustc_ast::*;
5use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
6use rustc_hir::attrs::AttributeKind;
7use rustc_hir::def::{DefKind, PerNS, Res};
8use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
9use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, find_attr};
10use rustc_index::{IndexSlice, IndexVec};
11use rustc_middle::span_bug;
12use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
13use rustc_span::edit_distance::find_best_match_for_name;
14use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
15use smallvec::{SmallVec, smallvec};
16use thin_vec::ThinVec;
17use tracing::instrument;
18
19use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault};
20use super::stability::{enabled_names, gate_unstable_abi};
21use super::{
22 AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
23 RelaxedBoundForbiddenReason, RelaxedBoundPolicy, 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 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) {
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) => {
80 assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
81 self.with_lctx(CRATE_NODE_ID, |lctx| {
82 let module = lctx.lower_mod(&c.items, &c.spans);
83 lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
85 hir::OwnerNode::Crate(module)
86 })
87 }
88 AstOwner::Item(item) => {
89 self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
90 }
91 AstOwner::AssocItem(item, ctxt) => {
92 self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
93 }
94 AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
95 hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
96 }),
97 }
98 }
99 }
100}
101
102impl<'hir> LoweringContext<'_, 'hir> {
103 pub(super) fn lower_mod(
104 &mut self,
105 items: &[P<Item>],
106 spans: &ModSpans,
107 ) -> &'hir hir::Mod<'hir> {
108 self.arena.alloc(hir::Mod {
109 spans: hir::ModSpans {
110 inner_span: self.lower_span(spans.inner_span),
111 inject_use_span: self.lower_span(spans.inject_use_span),
112 },
113 item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
114 })
115 }
116
117 pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
118 let mut node_ids = smallvec![hir::ItemId { owner_id: self.owner_id(i.id) }];
119 if let ItemKind::Use(use_tree) = &i.kind {
120 self.lower_item_id_use_tree(use_tree, &mut node_ids);
121 }
122 node_ids
123 }
124
125 fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
126 match &tree.kind {
127 UseTreeKind::Nested { items, .. } => {
128 for &(ref nested, id) in items {
129 vec.push(hir::ItemId { owner_id: self.owner_id(id) });
130 self.lower_item_id_use_tree(nested, vec);
131 }
132 }
133 UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
134 }
135 }
136
137 fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
138 let vis_span = self.lower_span(i.vis.span);
139 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
140 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
141 let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
142 let item = hir::Item {
143 owner_id: hir_id.expect_owner(),
144 kind,
145 vis_span,
146 span: self.lower_span(i.span),
147 has_delayed_lints: !self.delayed_lints.is_empty(),
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 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 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 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(i, 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, i, 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, i, 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 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 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
394 .arena
395 .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
396
397 let has_val = true;
400 let (defaultness, defaultness_span) = self.lower_defaultness(*defaultness, has_val);
401 let polarity = match polarity {
402 ImplPolarity::Positive => ImplPolarity::Positive,
403 ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
404 };
405 hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
406 constness: self.lower_constness(*constness),
407 safety: self.lower_safety(*safety, hir::Safety::Safe),
408 polarity,
409 defaultness,
410 defaultness_span,
411 generics,
412 of_trait: trait_ref,
413 self_ty: lowered_ty,
414 items: new_impl_items,
415 }))
416 }
417 ItemKind::Trait(box Trait {
418 constness,
419 is_auto,
420 safety,
421 ident,
422 generics,
423 bounds,
424 items,
425 }) => {
426 let constness = self.lower_constness(*constness);
427 let ident = self.lower_ident(*ident);
428 let (generics, (safety, items, bounds)) = self.lower_generics(
429 generics,
430 id,
431 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
432 |this| {
433 let bounds = this.lower_param_bounds(
434 bounds,
435 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
436 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
437 );
438 let items = this.arena.alloc_from_iter(
439 items.iter().map(|item| this.lower_trait_item_ref(item)),
440 );
441 let safety = this.lower_safety(*safety, hir::Safety::Safe);
442 (safety, items, bounds)
443 },
444 );
445 hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
446 }
447 ItemKind::TraitAlias(ident, generics, bounds) => {
448 let ident = self.lower_ident(*ident);
449 let (generics, bounds) = self.lower_generics(
450 generics,
451 id,
452 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
453 |this| {
454 this.lower_param_bounds(
455 bounds,
456 RelaxedBoundPolicy::Allowed,
457 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
458 )
459 },
460 );
461 hir::ItemKind::TraitAlias(ident, generics, bounds)
462 }
463 ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
464 let ident = self.lower_ident(*ident);
465 let body = P(self.lower_delim_args(body));
466 let def_id = self.local_def_id(id);
467 let def_kind = self.tcx.def_kind(def_id);
468 let DefKind::Macro(macro_kind) = def_kind else {
469 unreachable!(
470 "expected DefKind::Macro for macro item, found {}",
471 def_kind.descr(def_id.to_def_id())
472 );
473 };
474 let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
475 hir::ItemKind::Macro(ident, macro_def, macro_kind)
476 }
477 ItemKind::Delegation(box delegation) => {
478 let delegation_results = self.lower_delegation(delegation, id, false);
479 hir::ItemKind::Fn {
480 sig: delegation_results.sig,
481 ident: delegation_results.ident,
482 generics: delegation_results.generics,
483 body: delegation_results.body_id,
484 has_body: true,
485 }
486 }
487 ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
488 panic!("macros should have been expanded by now")
489 }
490 }
491 }
492
493 fn lower_const_item(
494 &mut self,
495 ty: &Ty,
496 span: Span,
497 body: Option<&Expr>,
498 impl_trait_position: ImplTraitPosition,
499 ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
500 let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
501 (ty, self.lower_const_body(span, body))
502 }
503
504 #[instrument(level = "debug", skip(self))]
505 fn lower_use_tree(
506 &mut self,
507 tree: &UseTree,
508 prefix: &Path,
509 id: NodeId,
510 vis_span: Span,
511 attrs: &'hir [hir::Attribute],
512 ) -> hir::ItemKind<'hir> {
513 let path = &tree.prefix;
514 let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
515
516 match tree.kind {
517 UseTreeKind::Simple(rename) => {
518 let mut ident = tree.ident();
519
520 let mut path = Path { segments, span: path.span, tokens: None };
522
523 if path.segments.len() > 1
525 && path.segments.last().unwrap().ident.name == kw::SelfLower
526 {
527 let _ = path.segments.pop();
528 if rename.is_none() {
529 ident = path.segments.last().unwrap().ident;
530 }
531 }
532
533 let res = self.lower_import_res(id, path.span);
534 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
535 let ident = self.lower_ident(ident);
536 hir::ItemKind::Use(path, hir::UseKind::Single(ident))
537 }
538 UseTreeKind::Glob => {
539 let res = self.expect_full_res(id);
540 let res = self.lower_res(res);
541 let res = match res {
543 Res::Def(DefKind::Mod | DefKind::Trait, _) => {
544 PerNS { type_ns: Some(res), value_ns: None, macro_ns: None }
545 }
546 Res::Def(DefKind::Enum, _) => {
547 PerNS { type_ns: None, value_ns: Some(res), macro_ns: None }
548 }
549 Res::Err => {
550 let err = Some(Res::Err);
552 PerNS { type_ns: err, value_ns: err, macro_ns: err }
553 }
554 _ => span_bug!(path.span, "bad glob res {:?}", res),
555 };
556 let path = Path { segments, span: path.span, tokens: None };
557 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
558 hir::ItemKind::Use(path, hir::UseKind::Glob)
559 }
560 UseTreeKind::Nested { items: ref trees, .. } => {
561 let span = prefix.span.to(path.span);
586 let prefix = Path { segments, span, tokens: None };
587
588 for &(ref use_tree, id) in trees {
590 let owner_id = self.owner_id(id);
591
592 self.with_hir_id_owner(id, |this| {
598 let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
602 if !attrs.is_empty() {
603 this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
604 }
605
606 let item = hir::Item {
607 owner_id,
608 kind,
609 vis_span,
610 span: this.lower_span(use_tree.span),
611 has_delayed_lints: !this.delayed_lints.is_empty(),
612 };
613 hir::OwnerNode::Item(this.arena.alloc(item))
614 });
615 }
616
617 let path = if trees.is_empty()
619 && !(prefix.segments.is_empty()
620 || prefix.segments.len() == 1
621 && prefix.segments[0].ident.name == kw::PathRoot)
622 {
623 let res = self.lower_import_res(id, span);
626 self.lower_use_path(res, &prefix, ParamMode::Explicit)
627 } else {
628 let span = self.lower_span(span);
631 self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span })
632 };
633 hir::ItemKind::Use(path, hir::UseKind::ListStem)
634 }
635 }
636 }
637
638 fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
639 match ctxt {
643 AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
644 AssocCtxt::Impl { of_trait } => {
645 hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
646 }
647 }
648 }
649
650 fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
651 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
652 let owner_id = hir_id.expect_owner();
653 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
654 let (ident, kind) = match &i.kind {
655 ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
656 let fdec = &sig.decl;
657 let itctx = ImplTraitContext::Universal;
658 let (generics, (decl, fn_args)) =
659 self.lower_generics(generics, i.id, itctx, |this| {
660 (
661 this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
663 this.lower_fn_params_to_idents(fdec),
664 )
665 });
666
667 let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
669
670 if define_opaque.is_some() {
671 self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
672 }
673
674 (
675 ident,
676 hir::ForeignItemKind::Fn(
677 hir::FnSig { header, decl, span: self.lower_span(sig.span) },
678 fn_args,
679 generics,
680 ),
681 )
682 }
683 ForeignItemKind::Static(box StaticItem {
684 ident,
685 ty,
686 mutability,
687 expr: _,
688 safety,
689 define_opaque,
690 }) => {
691 let ty =
692 self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
693 let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
694 if define_opaque.is_some() {
695 self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
696 }
697 (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
698 }
699 ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
700 (ident, hir::ForeignItemKind::Type)
701 }
702 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
703 };
704
705 let item = hir::ForeignItem {
706 owner_id,
707 ident: self.lower_ident(*ident),
708 kind,
709 vis_span: self.lower_span(i.vis.span),
710 span: self.lower_span(i.span),
711 has_delayed_lints: !self.delayed_lints.is_empty(),
712 };
713 self.arena.alloc(item)
714 }
715
716 fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId {
717 hir::ForeignItemId { owner_id: self.owner_id(i.id) }
718 }
719
720 fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
721 let hir_id = self.lower_node_id(v.id);
722 self.lower_attrs(hir_id, &v.attrs, v.span);
723 hir::Variant {
724 hir_id,
725 def_id: self.local_def_id(v.id),
726 data: self.lower_variant_data(hir_id, item_kind, &v.data),
727 disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
728 ident: self.lower_ident(v.ident),
729 span: self.lower_span(v.span),
730 }
731 }
732
733 fn lower_variant_data(
734 &mut self,
735 parent_id: hir::HirId,
736 item_kind: &ItemKind,
737 vdata: &VariantData,
738 ) -> hir::VariantData<'hir> {
739 match vdata {
740 VariantData::Struct { fields, recovered } => {
741 let fields = self
742 .arena
743 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
744
745 if let ItemKind::Union(..) = item_kind {
746 for field in &fields[..] {
747 if let Some(default) = field.default {
748 if self.tcx.features().default_field_values() {
752 self.dcx().emit_err(UnionWithDefault { span: default.span });
753 } else {
754 let _ = self.dcx().span_delayed_bug(
755 default.span,
756 "expected union default field values feature gate error but none \
757 was produced",
758 );
759 }
760 }
761 }
762 }
763
764 hir::VariantData::Struct { fields, recovered: *recovered }
765 }
766 VariantData::Tuple(fields, id) => {
767 let ctor_id = self.lower_node_id(*id);
768 self.alias_attrs(ctor_id, parent_id);
769 let fields = self
770 .arena
771 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
772 for field in &fields[..] {
773 if let Some(default) = field.default {
774 if self.tcx.features().default_field_values() {
779 self.dcx().emit_err(TupleStructWithDefault { span: default.span });
780 } else {
781 let _ = self.dcx().span_delayed_bug(
782 default.span,
783 "expected `default values on `struct` fields aren't supported` \
784 feature-gate error but none was produced",
785 );
786 }
787 }
788 }
789 hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))
790 }
791 VariantData::Unit(id) => {
792 let ctor_id = self.lower_node_id(*id);
793 self.alias_attrs(ctor_id, parent_id);
794 hir::VariantData::Unit(ctor_id, self.local_def_id(*id))
795 }
796 }
797 }
798
799 pub(super) fn lower_field_def(
800 &mut self,
801 (index, f): (usize, &FieldDef),
802 ) -> hir::FieldDef<'hir> {
803 let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
804 let hir_id = self.lower_node_id(f.id);
805 self.lower_attrs(hir_id, &f.attrs, f.span);
806 hir::FieldDef {
807 span: self.lower_span(f.span),
808 hir_id,
809 def_id: self.local_def_id(f.id),
810 ident: match f.ident {
811 Some(ident) => self.lower_ident(ident),
812 None => Ident::new(sym::integer(index), self.lower_span(f.span)),
814 },
815 vis_span: self.lower_span(f.vis.span),
816 default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
817 ty,
818 safety: self.lower_safety(f.safety, hir::Safety::Safe),
819 }
820 }
821
822 fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
823 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
824 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
825 let trait_item_def_id = hir_id.expect_owner();
826
827 let (ident, generics, kind, has_default) = match &i.kind {
828 AssocItemKind::Const(box ConstItem {
829 ident,
830 generics,
831 ty,
832 expr,
833 define_opaque,
834 ..
835 }) => {
836 let (generics, kind) = self.lower_generics(
837 generics,
838 i.id,
839 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
840 |this| {
841 let ty = this
842 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
843 let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
844
845 hir::TraitItemKind::Const(ty, body)
846 },
847 );
848
849 if define_opaque.is_some() {
850 if expr.is_some() {
851 self.lower_define_opaque(hir_id, &define_opaque);
852 } else {
853 self.dcx().span_err(
854 i.span,
855 "only trait consts with default bodies can define opaque types",
856 );
857 }
858 }
859
860 (*ident, generics, kind, expr.is_some())
861 }
862 AssocItemKind::Fn(box Fn {
863 sig, ident, generics, body: None, define_opaque, ..
864 }) => {
865 let idents = self.lower_fn_params_to_idents(&sig.decl);
868 let (generics, sig) = self.lower_method_sig(
869 generics,
870 sig,
871 i.id,
872 FnDeclKind::Trait,
873 sig.header.coroutine_kind,
874 attrs,
875 );
876 if define_opaque.is_some() {
877 self.dcx().span_err(
878 i.span,
879 "only trait methods with default bodies can define opaque types",
880 );
881 }
882 (
883 *ident,
884 generics,
885 hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),
886 false,
887 )
888 }
889 AssocItemKind::Fn(box Fn {
890 sig,
891 ident,
892 generics,
893 body: Some(body),
894 contract,
895 define_opaque,
896 ..
897 }) => {
898 let body_id = self.lower_maybe_coroutine_body(
899 sig.span,
900 i.span,
901 hir_id,
902 &sig.decl,
903 sig.header.coroutine_kind,
904 Some(body),
905 attrs,
906 contract.as_deref(),
907 );
908 let (generics, sig) = self.lower_method_sig(
909 generics,
910 sig,
911 i.id,
912 FnDeclKind::Trait,
913 sig.header.coroutine_kind,
914 attrs,
915 );
916 self.lower_define_opaque(hir_id, &define_opaque);
917 (
918 *ident,
919 generics,
920 hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
921 true,
922 )
923 }
924 AssocItemKind::Type(box TyAlias {
925 ident, generics, where_clauses, bounds, ty, ..
926 }) => {
927 let mut generics = generics.clone();
928 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
929 let (generics, kind) = self.lower_generics(
930 &generics,
931 i.id,
932 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
933 |this| {
934 let ty = ty.as_ref().map(|x| {
935 this.lower_ty(
936 x,
937 ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
938 )
939 });
940 hir::TraitItemKind::Type(
941 this.lower_param_bounds(
942 bounds,
943 RelaxedBoundPolicy::Allowed,
944 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
945 ),
946 ty,
947 )
948 },
949 );
950 (*ident, generics, kind, ty.is_some())
951 }
952 AssocItemKind::Delegation(box delegation) => {
953 let delegation_results = self.lower_delegation(delegation, i.id, false);
954 let item_kind = hir::TraitItemKind::Fn(
955 delegation_results.sig,
956 hir::TraitFn::Provided(delegation_results.body_id),
957 );
958 (delegation.ident, delegation_results.generics, item_kind, true)
959 }
960 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
961 panic!("macros should have been expanded by now")
962 }
963 };
964
965 let item = hir::TraitItem {
966 owner_id: trait_item_def_id,
967 ident: self.lower_ident(ident),
968 generics,
969 kind,
970 span: self.lower_span(i.span),
971 defaultness: hir::Defaultness::Default { has_value: has_default },
972 has_delayed_lints: !self.delayed_lints.is_empty(),
973 };
974 self.arena.alloc(item)
975 }
976
977 fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId {
978 hir::TraitItemId { owner_id: self.owner_id(i.id) }
979 }
980
981 pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {
983 self.expr(span, hir::ExprKind::Err(guar))
984 }
985
986 fn lower_impl_item(
987 &mut self,
988 i: &AssocItem,
989 is_in_trait_impl: bool,
990 ) -> &'hir hir::ImplItem<'hir> {
991 let has_value = true;
993 let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
994 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
995 let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
996
997 let (ident, (generics, kind)) = match &i.kind {
998 AssocItemKind::Const(box ConstItem {
999 ident,
1000 generics,
1001 ty,
1002 expr,
1003 define_opaque,
1004 ..
1005 }) => (
1006 *ident,
1007 self.lower_generics(
1008 generics,
1009 i.id,
1010 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1011 |this| {
1012 let ty = this
1013 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1014 let body = this.lower_const_body(i.span, expr.as_deref());
1015 this.lower_define_opaque(hir_id, &define_opaque);
1016 hir::ImplItemKind::Const(ty, body)
1017 },
1018 ),
1019 ),
1020 AssocItemKind::Fn(box Fn {
1021 sig,
1022 ident,
1023 generics,
1024 body,
1025 contract,
1026 define_opaque,
1027 ..
1028 }) => {
1029 let body_id = self.lower_maybe_coroutine_body(
1030 sig.span,
1031 i.span,
1032 hir_id,
1033 &sig.decl,
1034 sig.header.coroutine_kind,
1035 body.as_deref(),
1036 attrs,
1037 contract.as_deref(),
1038 );
1039 let (generics, sig) = self.lower_method_sig(
1040 generics,
1041 sig,
1042 i.id,
1043 if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
1044 sig.header.coroutine_kind,
1045 attrs,
1046 );
1047 self.lower_define_opaque(hir_id, &define_opaque);
1048
1049 (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
1050 }
1051 AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => {
1052 let mut generics = generics.clone();
1053 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
1054 (
1055 *ident,
1056 self.lower_generics(
1057 &generics,
1058 i.id,
1059 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1060 |this| match ty {
1061 None => {
1062 let guar = this.dcx().span_delayed_bug(
1063 i.span,
1064 "expected to lower associated type, but it was missing",
1065 );
1066 let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
1067 hir::ImplItemKind::Type(ty)
1068 }
1069 Some(ty) => {
1070 let ty = this.lower_ty(
1071 ty,
1072 ImplTraitContext::OpaqueTy {
1073 origin: hir::OpaqueTyOrigin::TyAlias {
1074 parent: this.local_def_id(i.id),
1075 in_assoc_ty: true,
1076 },
1077 },
1078 );
1079 hir::ImplItemKind::Type(ty)
1080 }
1081 },
1082 ),
1083 )
1084 }
1085 AssocItemKind::Delegation(box delegation) => {
1086 let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
1087 (
1088 delegation.ident,
1089 (
1090 delegation_results.generics,
1091 hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
1092 ),
1093 )
1094 }
1095 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1096 panic!("macros should have been expanded by now")
1097 }
1098 };
1099
1100 let item = hir::ImplItem {
1101 owner_id: hir_id.expect_owner(),
1102 ident: self.lower_ident(ident),
1103 generics,
1104 kind,
1105 vis_span: self.lower_span(i.vis.span),
1106 span: self.lower_span(i.span),
1107 defaultness,
1108 has_delayed_lints: !self.delayed_lints.is_empty(),
1109 trait_item_def_id: self
1110 .resolver
1111 .get_partial_res(i.id)
1112 .map(|r| r.expect_full_res().opt_def_id())
1113 .unwrap_or(None),
1114 };
1115 self.arena.alloc(item)
1116 }
1117
1118 fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId {
1119 hir::ImplItemId { owner_id: self.owner_id(i.id) }
1120 }
1121
1122 fn lower_defaultness(
1123 &self,
1124 d: Defaultness,
1125 has_value: bool,
1126 ) -> (hir::Defaultness, Option<Span>) {
1127 match d {
1128 Defaultness::Default(sp) => {
1129 (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
1130 }
1131 Defaultness::Final => {
1132 assert!(has_value);
1133 (hir::Defaultness::Final, None)
1134 }
1135 }
1136 }
1137
1138 fn record_body(
1139 &mut self,
1140 params: &'hir [hir::Param<'hir>],
1141 value: hir::Expr<'hir>,
1142 ) -> hir::BodyId {
1143 let body = hir::Body { params, value: self.arena.alloc(value) };
1144 let id = body.id();
1145 assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
1146 self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
1147 id
1148 }
1149
1150 pub(super) fn lower_body(
1151 &mut self,
1152 f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
1153 ) -> hir::BodyId {
1154 let prev_coroutine_kind = self.coroutine_kind.take();
1155 let task_context = self.task_context.take();
1156 let (parameters, result) = f(self);
1157 let body_id = self.record_body(parameters, result);
1158 self.task_context = task_context;
1159 self.coroutine_kind = prev_coroutine_kind;
1160 body_id
1161 }
1162
1163 fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1164 let hir_id = self.lower_node_id(param.id);
1165 self.lower_attrs(hir_id, ¶m.attrs, param.span);
1166 hir::Param {
1167 hir_id,
1168 pat: self.lower_pat(¶m.pat),
1169 ty_span: self.lower_span(param.ty.span),
1170 span: self.lower_span(param.span),
1171 }
1172 }
1173
1174 pub(super) fn lower_fn_body(
1175 &mut self,
1176 decl: &FnDecl,
1177 contract: Option<&FnContract>,
1178 body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
1179 ) -> hir::BodyId {
1180 self.lower_body(|this| {
1181 let params =
1182 this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
1183
1184 if let Some(contract) = contract {
1192 let precond = if let Some(req) = &contract.requires {
1193 let lowered_req = this.lower_expr_mut(&req);
1195 let req_span = this.mark_span_with_reason(
1196 DesugaringKind::Contract,
1197 lowered_req.span,
1198 None,
1199 );
1200 let precond = this.expr_call_lang_item_fn_mut(
1201 req_span,
1202 hir::LangItem::ContractCheckRequires,
1203 &*arena_vec![this; lowered_req],
1204 );
1205 Some(this.stmt_expr(req.span, precond))
1206 } else {
1207 None
1208 };
1209 let (postcond, body) = if let Some(ens) = &contract.ensures {
1210 let ens_span = this.lower_span(ens.span);
1211 let ens_span =
1212 this.mark_span_with_reason(DesugaringKind::Contract, ens_span, None);
1213 let check_ident: Ident =
1215 Ident::from_str_and_span("__ensures_checker", ens_span);
1216 let (checker_pat, check_hir_id) = this.pat_ident_binding_mode_mut(
1217 ens_span,
1218 check_ident,
1219 hir::BindingMode::NONE,
1220 );
1221 let lowered_ens = this.lower_expr_mut(&ens);
1222 let postcond_checker = this.expr_call_lang_item_fn(
1223 ens_span,
1224 hir::LangItem::ContractBuildCheckEnsures,
1225 &*arena_vec![this; lowered_ens],
1226 );
1227 let postcond = this.stmt_let_pat(
1228 None,
1229 ens_span,
1230 Some(postcond_checker),
1231 this.arena.alloc(checker_pat),
1232 hir::LocalSource::Contract,
1233 );
1234
1235 this.contract_ensures = Some((ens_span, check_ident, check_hir_id));
1238 let body = this.arena.alloc(body(this));
1239
1240 let body = this.inject_ensures_check(body, ens_span, check_ident, check_hir_id);
1242 (Some(postcond), body)
1243 } else {
1244 let body = &*this.arena.alloc(body(this));
1245 (None, body)
1246 };
1247 let wrapped_body = this.block_all(
1249 body.span,
1250 this.arena.alloc_from_iter([precond, postcond].into_iter().flatten()),
1251 Some(body),
1252 );
1253 (params, this.expr_block(wrapped_body))
1254 } else {
1255 (params, body(this))
1256 }
1257 })
1258 }
1259
1260 fn lower_fn_body_block(
1261 &mut self,
1262 decl: &FnDecl,
1263 body: &Block,
1264 contract: Option<&FnContract>,
1265 ) -> hir::BodyId {
1266 self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
1267 }
1268
1269 pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1270 self.lower_body(|this| {
1271 (
1272 &[],
1273 match expr {
1274 Some(expr) => this.lower_expr_mut(expr),
1275 None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
1276 },
1277 )
1278 })
1279 }
1280
1281 fn lower_maybe_coroutine_body(
1284 &mut self,
1285 fn_decl_span: Span,
1286 span: Span,
1287 fn_id: hir::HirId,
1288 decl: &FnDecl,
1289 coroutine_kind: Option<CoroutineKind>,
1290 body: Option<&Block>,
1291 attrs: &'hir [hir::Attribute],
1292 contract: Option<&FnContract>,
1293 ) -> hir::BodyId {
1294 let Some(body) = body else {
1295 return self.lower_fn_body(decl, contract, |this| {
1299 if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
1300 || this.tcx.is_sdylib_interface_build()
1301 {
1302 let span = this.lower_span(span);
1303 let empty_block = hir::Block {
1304 hir_id: this.next_id(),
1305 stmts: &[],
1306 expr: None,
1307 rules: hir::BlockCheckMode::DefaultBlock,
1308 span,
1309 targeted_by_break: false,
1310 };
1311 let loop_ = hir::ExprKind::Loop(
1312 this.arena.alloc(empty_block),
1313 None,
1314 hir::LoopSource::Loop,
1315 span,
1316 );
1317 hir::Expr { hir_id: this.next_id(), kind: loop_, span }
1318 } else {
1319 this.expr_err(span, this.dcx().has_errors().unwrap())
1320 }
1321 });
1322 };
1323 let Some(coroutine_kind) = coroutine_kind else {
1324 return self.lower_fn_body_block(decl, body, contract);
1326 };
1327 self.lower_body(|this| {
1329 let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1330 decl,
1331 |this| this.lower_block_expr(body),
1332 fn_decl_span,
1333 body.span,
1334 coroutine_kind,
1335 hir::CoroutineSource::Fn,
1336 );
1337
1338 let hir_id = expr.hir_id;
1340 this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1341
1342 (parameters, expr)
1343 })
1344 }
1345
1346 pub(crate) fn lower_coroutine_body_with_moved_arguments(
1351 &mut self,
1352 decl: &FnDecl,
1353 lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
1354 fn_decl_span: Span,
1355 body_span: Span,
1356 coroutine_kind: CoroutineKind,
1357 coroutine_source: hir::CoroutineSource,
1358 ) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {
1359 let mut parameters: Vec<hir::Param<'_>> = Vec::new();
1360 let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
1361
1362 for (index, parameter) in decl.inputs.iter().enumerate() {
1395 let parameter = self.lower_param(parameter);
1396 let span = parameter.pat.span;
1397
1398 let (ident, is_simple_parameter) = match parameter.pat.kind {
1401 hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),
1402 hir::PatKind::Binding(_, _, ident, _) => (ident, false),
1406 hir::PatKind::Wild => (Ident::with_dummy_span(rustc_span::kw::Underscore), false),
1407 _ => {
1408 let name = format!("__arg{index}");
1410 let ident = Ident::from_str(&name);
1411
1412 (ident, false)
1413 }
1414 };
1415
1416 let desugared_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1417
1418 let stmt_attrs = self.attrs.get(¶meter.hir_id.local_id).copied();
1424 let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident);
1425 let new_parameter = hir::Param {
1426 hir_id: parameter.hir_id,
1427 pat: new_parameter_pat,
1428 ty_span: self.lower_span(parameter.ty_span),
1429 span: self.lower_span(parameter.span),
1430 };
1431
1432 if is_simple_parameter {
1433 let expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1437 let stmt = self.stmt_let_pat(
1438 stmt_attrs,
1439 desugared_span,
1440 Some(expr),
1441 parameter.pat,
1442 hir::LocalSource::AsyncFn,
1443 );
1444 statements.push(stmt);
1445 } else {
1446 let (move_pat, move_id) =
1462 self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);
1463 let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1464 let move_stmt = self.stmt_let_pat(
1465 None,
1466 desugared_span,
1467 Some(move_expr),
1468 move_pat,
1469 hir::LocalSource::AsyncFn,
1470 );
1471
1472 let pattern_expr = self.expr_ident(desugared_span, ident, move_id);
1475 let pattern_stmt = self.stmt_let_pat(
1476 stmt_attrs,
1477 desugared_span,
1478 Some(pattern_expr),
1479 parameter.pat,
1480 hir::LocalSource::AsyncFn,
1481 );
1482
1483 statements.push(move_stmt);
1484 statements.push(pattern_stmt);
1485 };
1486
1487 parameters.push(new_parameter);
1488 }
1489
1490 let mkbody = |this: &mut LoweringContext<'_, 'hir>| {
1491 let user_body = lower_body(this);
1493
1494 let desugared_span =
1496 this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
1497 let user_body = this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
1498
1499 let body = this.block_all(
1509 desugared_span,
1510 this.arena.alloc_from_iter(statements),
1511 Some(user_body),
1512 );
1513
1514 this.expr_block(body)
1515 };
1516 let desugaring_kind = match coroutine_kind {
1517 CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,
1518 CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,
1519 CoroutineKind::AsyncGen { .. } => hir::CoroutineDesugaring::AsyncGen,
1520 };
1521 let closure_id = coroutine_kind.closure_id();
1522
1523 let coroutine_expr = self.make_desugared_coroutine_expr(
1524 CaptureBy::Ref,
1529 closure_id,
1530 None,
1531 fn_decl_span,
1532 body_span,
1533 desugaring_kind,
1534 coroutine_source,
1535 mkbody,
1536 );
1537
1538 let expr = hir::Expr {
1539 hir_id: self.lower_node_id(closure_id),
1540 kind: coroutine_expr,
1541 span: self.lower_span(body_span),
1542 };
1543
1544 (self.arena.alloc_from_iter(parameters), expr)
1545 }
1546
1547 fn lower_method_sig(
1548 &mut self,
1549 generics: &Generics,
1550 sig: &FnSig,
1551 id: NodeId,
1552 kind: FnDeclKind,
1553 coroutine_kind: Option<CoroutineKind>,
1554 attrs: &[hir::Attribute],
1555 ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
1556 let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
1557 let itctx = ImplTraitContext::Universal;
1558 let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1559 this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1560 });
1561 (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
1562 }
1563
1564 pub(super) fn lower_fn_header(
1565 &mut self,
1566 h: FnHeader,
1567 default_safety: hir::Safety,
1568 attrs: &[hir::Attribute],
1569 ) -> hir::FnHeader {
1570 let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
1571 hir::IsAsync::Async(self.lower_span(span))
1572 } else {
1573 hir::IsAsync::NotAsync
1574 };
1575
1576 let safety = self.lower_safety(h.safety, default_safety);
1577
1578 let safety = if find_attr!(attrs, AttributeKind::TargetFeature { .. })
1580 && safety.is_safe()
1581 && !self.tcx.sess.target.is_like_wasm
1582 {
1583 hir::HeaderSafety::SafeTargetFeatures
1584 } else {
1585 safety.into()
1586 };
1587
1588 hir::FnHeader {
1589 safety,
1590 asyncness,
1591 constness: self.lower_constness(h.constness),
1592 abi: self.lower_extern(h.ext),
1593 }
1594 }
1595
1596 pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {
1597 let ast::StrLit { symbol_unescaped, span, .. } = abi_str;
1598 let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| {
1599 self.error_on_invalid_abi(abi_str);
1600 ExternAbi::Rust
1601 });
1602 let tcx = self.tcx;
1603
1604 if !tcx.sess.target.is_abi_supported(extern_abi) {
1606 let mut err = struct_span_code_err!(
1607 tcx.dcx(),
1608 span,
1609 E0570,
1610 "{extern_abi} is not a supported ABI for the current target",
1611 );
1612
1613 if let ExternAbi::Stdcall { unwind } = extern_abi {
1614 let c_abi = ExternAbi::C { unwind };
1615 let system_abi = ExternAbi::System { unwind };
1616 err.help(format!("if you need `extern {extern_abi}` on win32 and `extern {c_abi}` everywhere else, \
1617 use `extern {system_abi}`"
1618 ));
1619 }
1620 err.emit();
1621 }
1622 gate_unstable_abi(tcx.sess, tcx.features(), span, extern_abi);
1625 extern_abi
1626 }
1627
1628 pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {
1629 match ext {
1630 Extern::None => ExternAbi::Rust,
1631 Extern::Implicit(_) => ExternAbi::FALLBACK,
1632 Extern::Explicit(abi, _) => self.lower_abi(abi),
1633 }
1634 }
1635
1636 fn error_on_invalid_abi(&self, abi: StrLit) {
1637 let abi_names = enabled_names(self.tcx.features(), abi.span)
1638 .iter()
1639 .map(|s| Symbol::intern(s))
1640 .collect::<Vec<_>>();
1641 let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
1642 self.dcx().emit_err(InvalidAbi {
1643 abi: abi.symbol_unescaped,
1644 span: abi.span,
1645 suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
1646 span: abi.span,
1647 suggestion: suggested_name.to_string(),
1648 }),
1649 command: "rustc --print=calling-conventions".to_string(),
1650 });
1651 }
1652
1653 pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
1654 match c {
1655 Const::Yes(_) => hir::Constness::Const,
1656 Const::No => hir::Constness::NotConst,
1657 }
1658 }
1659
1660 pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {
1661 match s {
1662 Safety::Unsafe(_) => hir::Safety::Unsafe,
1663 Safety::Default => default,
1664 Safety::Safe(_) => hir::Safety::Safe,
1665 }
1666 }
1667
1668 #[instrument(level = "debug", skip(self, f))]
1671 fn lower_generics<T>(
1672 &mut self,
1673 generics: &Generics,
1674 parent_node_id: NodeId,
1675 itctx: ImplTraitContext,
1676 f: impl FnOnce(&mut Self) -> T,
1677 ) -> (&'hir hir::Generics<'hir>, T) {
1678 assert!(self.impl_trait_defs.is_empty());
1679 assert!(self.impl_trait_bounds.is_empty());
1680
1681 let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
1682 predicates.extend(generics.params.iter().filter_map(|param| {
1683 self.lower_generic_bound_predicate(
1684 param.ident,
1685 param.id,
1686 ¶m.kind,
1687 ¶m.bounds,
1688 param.colon_span,
1689 generics.span,
1690 RelaxedBoundPolicy::Allowed,
1691 itctx,
1692 PredicateOrigin::GenericParam,
1693 )
1694 }));
1695 predicates.extend(
1696 generics
1697 .where_clause
1698 .predicates
1699 .iter()
1700 .map(|predicate| self.lower_where_predicate(predicate, &generics.params)),
1701 );
1702
1703 let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self
1704 .lower_generic_params_mut(&generics.params, hir::GenericParamSource::Generics)
1705 .collect();
1706
1707 let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);
1709 params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
1710 self.lifetime_res_to_generic_param(
1711 ident,
1712 node_id,
1713 res,
1714 hir::GenericParamSource::Generics,
1715 )
1716 }));
1717
1718 let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();
1719 let where_clause_span = self.lower_span(generics.where_clause.span);
1720 let span = self.lower_span(generics.span);
1721 let res = f(self);
1722
1723 let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
1724 params.extend(impl_trait_defs.into_iter());
1725
1726 let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
1727 predicates.extend(impl_trait_bounds.into_iter());
1728
1729 let lowered_generics = self.arena.alloc(hir::Generics {
1730 params: self.arena.alloc_from_iter(params),
1731 predicates: self.arena.alloc_from_iter(predicates),
1732 has_where_clause_predicates,
1733 where_clause_span,
1734 span,
1735 });
1736
1737 (lowered_generics, res)
1738 }
1739
1740 pub(super) fn lower_define_opaque(
1741 &mut self,
1742 hir_id: HirId,
1743 define_opaque: &Option<ThinVec<(NodeId, Path)>>,
1744 ) {
1745 assert_eq!(self.define_opaque, None);
1746 assert!(hir_id.is_owner());
1747 let Some(define_opaque) = define_opaque.as_ref() else {
1748 return;
1749 };
1750 let define_opaque = define_opaque.iter().filter_map(|(id, path)| {
1751 let res = self.resolver.get_partial_res(*id);
1752 let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {
1753 self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
1754 return None;
1755 };
1756 let Some(did) = did.as_local() else {
1757 self.dcx().span_err(
1758 path.span,
1759 "only opaque types defined in the local crate can be defined",
1760 );
1761 return None;
1762 };
1763 Some((self.lower_span(path.span), did))
1764 });
1765 let define_opaque = self.arena.alloc_from_iter(define_opaque);
1766 self.define_opaque = Some(define_opaque);
1767 }
1768
1769 pub(super) fn lower_generic_bound_predicate(
1770 &mut self,
1771 ident: Ident,
1772 id: NodeId,
1773 kind: &GenericParamKind,
1774 bounds: &[GenericBound],
1775 colon_span: Option<Span>,
1776 parent_span: Span,
1777 rbp: RelaxedBoundPolicy<'_>,
1778 itctx: ImplTraitContext,
1779 origin: PredicateOrigin,
1780 ) -> Option<hir::WherePredicate<'hir>> {
1781 if bounds.is_empty() {
1783 return None;
1784 }
1785
1786 let bounds = self.lower_param_bounds(bounds, rbp, itctx);
1787
1788 let param_span = ident.span;
1789
1790 let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());
1792 let span = bounds.iter().fold(span_start, |span_accum, bound| {
1793 match bound.span().find_ancestor_inside(parent_span) {
1794 Some(bound_span) => span_accum.to(bound_span),
1795 None => span_accum,
1796 }
1797 });
1798 let span = self.lower_span(span);
1799 let hir_id = self.next_id();
1800 let kind = self.arena.alloc(match kind {
1801 GenericParamKind::Const { .. } => return None,
1802 GenericParamKind::Type { .. } => {
1803 let def_id = self.local_def_id(id).to_def_id();
1804 let hir_id = self.next_id();
1805 let res = Res::Def(DefKind::TyParam, def_id);
1806 let ident = self.lower_ident(ident);
1807 let ty_path = self.arena.alloc(hir::Path {
1808 span: self.lower_span(param_span),
1809 res,
1810 segments: self
1811 .arena
1812 .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
1813 });
1814 let ty_id = self.next_id();
1815 let bounded_ty =
1816 self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
1817 hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1818 bounded_ty: self.arena.alloc(bounded_ty),
1819 bounds,
1820 bound_generic_params: &[],
1821 origin,
1822 })
1823 }
1824 GenericParamKind::Lifetime => {
1825 let lt_id = self.next_node_id();
1826 let lifetime =
1827 self.new_named_lifetime(id, lt_id, ident, LifetimeSource::Other, ident.into());
1828 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1829 lifetime,
1830 bounds,
1831 in_where_clause: false,
1832 })
1833 }
1834 });
1835 Some(hir::WherePredicate { hir_id, span, kind })
1836 }
1837
1838 fn lower_where_predicate(
1839 &mut self,
1840 pred: &WherePredicate,
1841 params: &[ast::GenericParam],
1842 ) -> hir::WherePredicate<'hir> {
1843 let hir_id = self.lower_node_id(pred.id);
1844 let span = self.lower_span(pred.span);
1845 self.lower_attrs(hir_id, &pred.attrs, span);
1846 let kind = self.arena.alloc(match &pred.kind {
1847 WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1848 bound_generic_params,
1849 bounded_ty,
1850 bounds,
1851 }) => {
1852 let rbp = if bound_generic_params.is_empty() {
1853 RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params)
1854 } else {
1855 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope)
1856 };
1857 hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1858 bound_generic_params: self.lower_generic_params(
1859 bound_generic_params,
1860 hir::GenericParamSource::Binder,
1861 ),
1862 bounded_ty: self.lower_ty(
1863 bounded_ty,
1864 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1865 ),
1866 bounds: self.lower_param_bounds(
1867 bounds,
1868 rbp,
1869 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1870 ),
1871 origin: PredicateOrigin::WhereClause,
1872 })
1873 }
1874 WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
1875 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1876 lifetime: self.lower_lifetime(
1877 lifetime,
1878 LifetimeSource::Other,
1879 lifetime.ident.into(),
1880 ),
1881 bounds: self.lower_param_bounds(
1882 bounds,
1883 RelaxedBoundPolicy::Allowed,
1884 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1885 ),
1886 in_where_clause: true,
1887 })
1888 }
1889 WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
1890 hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
1891 lhs_ty: self
1892 .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1893 rhs_ty: self
1894 .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1895 })
1896 }
1897 });
1898 hir::WherePredicate { hir_id, span, kind }
1899 }
1900}