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