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