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