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