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 }) => {
348 let itctx = ImplTraitContext::Universal;
362 let (generics, (of_trait, lowered_ty)) =
363 self.lower_generics(ast_generics, id, itctx, |this| {
364 let of_trait = of_trait
365 .as_deref()
366 .map(|of_trait| this.lower_trait_impl_header(of_trait));
367
368 let lowered_ty = this.lower_ty(
369 ty,
370 ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
371 );
372
373 (of_trait, lowered_ty)
374 });
375
376 let new_impl_items = self
377 .arena
378 .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
379
380 hir::ItemKind::Impl(hir::Impl {
381 generics,
382 of_trait,
383 self_ty: lowered_ty,
384 items: new_impl_items,
385 })
386 }
387 ItemKind::Trait(box Trait {
388 constness,
389 is_auto,
390 safety,
391 ident,
392 generics,
393 bounds,
394 items,
395 }) => {
396 let constness = self.lower_constness(*constness);
397 let ident = self.lower_ident(*ident);
398 let (generics, (safety, items, bounds)) = self.lower_generics(
399 generics,
400 id,
401 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
402 |this| {
403 let bounds = this.lower_param_bounds(
404 bounds,
405 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
406 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
407 );
408 let items = this.arena.alloc_from_iter(
409 items.iter().map(|item| this.lower_trait_item_ref(item)),
410 );
411 let safety = this.lower_safety(*safety, hir::Safety::Safe);
412 (safety, items, bounds)
413 },
414 );
415 hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
416 }
417 ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
418 let constness = self.lower_constness(*constness);
419 let ident = self.lower_ident(*ident);
420 let (generics, bounds) = self.lower_generics(
421 generics,
422 id,
423 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
424 |this| {
425 this.lower_param_bounds(
426 bounds,
427 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitAlias),
428 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
429 )
430 },
431 );
432 hir::ItemKind::TraitAlias(constness, ident, generics, bounds)
433 }
434 ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
435 let ident = self.lower_ident(*ident);
436 let body = Box::new(self.lower_delim_args(body));
437 let def_id = self.local_def_id(id);
438 let def_kind = self.tcx.def_kind(def_id);
439 let DefKind::Macro(macro_kinds) = def_kind else {
440 unreachable!(
441 "expected DefKind::Macro for macro item, found {}",
442 def_kind.descr(def_id.to_def_id())
443 );
444 };
445 let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
446 hir::ItemKind::Macro(ident, macro_def, macro_kinds)
447 }
448 ItemKind::Delegation(box delegation) => {
449 let delegation_results = self.lower_delegation(delegation, id, false);
450 hir::ItemKind::Fn {
451 sig: delegation_results.sig,
452 ident: delegation_results.ident,
453 generics: delegation_results.generics,
454 body: delegation_results.body_id,
455 has_body: true,
456 }
457 }
458 ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
459 panic!("macros should have been expanded by now")
460 }
461 }
462 }
463
464 #[instrument(level = "debug", skip(self))]
465 fn lower_use_tree(
466 &mut self,
467 tree: &UseTree,
468 prefix: &Path,
469 id: NodeId,
470 vis_span: Span,
471 attrs: &'hir [hir::Attribute],
472 ) -> hir::ItemKind<'hir> {
473 let path = &tree.prefix;
474 let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
475
476 match tree.kind {
477 UseTreeKind::Simple(rename) => {
478 let mut ident = tree.ident();
479
480 let mut path = Path { segments, span: path.span, tokens: None };
482
483 if path.segments.len() > 1
485 && path.segments.last().unwrap().ident.name == kw::SelfLower
486 {
487 let _ = path.segments.pop();
488 if rename.is_none() {
489 ident = path.segments.last().unwrap().ident;
490 }
491 }
492
493 let res = self.lower_import_res(id, path.span);
494 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
495 let ident = self.lower_ident(ident);
496 hir::ItemKind::Use(path, hir::UseKind::Single(ident))
497 }
498 UseTreeKind::Glob => {
499 let res = self.expect_full_res(id);
500 let res = self.lower_res(res);
501 let res = match res {
503 Res::Def(DefKind::Mod | DefKind::Trait, _) => {
504 PerNS { type_ns: Some(res), value_ns: None, macro_ns: None }
505 }
506 Res::Def(DefKind::Enum, _) => {
507 PerNS { type_ns: None, value_ns: Some(res), macro_ns: None }
508 }
509 Res::Err => {
510 let err = Some(Res::Err);
512 PerNS { type_ns: err, value_ns: err, macro_ns: err }
513 }
514 _ => span_bug!(path.span, "bad glob res {:?}", res),
515 };
516 let path = Path { segments, span: path.span, tokens: None };
517 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
518 hir::ItemKind::Use(path, hir::UseKind::Glob)
519 }
520 UseTreeKind::Nested { items: ref trees, .. } => {
521 let span = prefix.span.to(path.span);
546 let prefix = Path { segments, span, tokens: None };
547
548 for &(ref use_tree, id) in trees {
550 let owner_id = self.owner_id(id);
551
552 self.with_hir_id_owner(id, |this| {
558 let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
562 if !attrs.is_empty() {
563 this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
564 }
565
566 let item = hir::Item {
567 owner_id,
568 kind,
569 vis_span,
570 span: this.lower_span(use_tree.span),
571 has_delayed_lints: !this.delayed_lints.is_empty(),
572 };
573 hir::OwnerNode::Item(this.arena.alloc(item))
574 });
575 }
576
577 let path = if trees.is_empty()
579 && !(prefix.segments.is_empty()
580 || prefix.segments.len() == 1
581 && prefix.segments[0].ident.name == kw::PathRoot)
582 {
583 let res = self.lower_import_res(id, span);
586 self.lower_use_path(res, &prefix, ParamMode::Explicit)
587 } else {
588 let span = self.lower_span(span);
591 self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span })
592 };
593 hir::ItemKind::Use(path, hir::UseKind::ListStem)
594 }
595 }
596 }
597
598 fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
599 match ctxt {
603 AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
604 AssocCtxt::Impl { of_trait } => {
605 hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
606 }
607 }
608 }
609
610 fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
611 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
612 let owner_id = hir_id.expect_owner();
613 let attrs =
614 self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind));
615 let (ident, kind) = match &i.kind {
616 ForeignItemKind::Fn(box Fn { sig, ident, generics, define_opaque, .. }) => {
617 let fdec = &sig.decl;
618 let itctx = ImplTraitContext::Universal;
619 let (generics, (decl, fn_args)) =
620 self.lower_generics(generics, i.id, itctx, |this| {
621 (
622 this.lower_fn_decl(fdec, i.id, sig.span, FnDeclKind::ExternFn, None),
624 this.lower_fn_params_to_idents(fdec),
625 )
626 });
627
628 let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
630
631 if define_opaque.is_some() {
632 self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
633 }
634
635 (
636 ident,
637 hir::ForeignItemKind::Fn(
638 hir::FnSig { header, decl, span: self.lower_span(sig.span) },
639 fn_args,
640 generics,
641 ),
642 )
643 }
644 ForeignItemKind::Static(box StaticItem {
645 ident,
646 ty,
647 mutability,
648 expr: _,
649 safety,
650 define_opaque,
651 }) => {
652 let ty =
653 self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
654 let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
655 if define_opaque.is_some() {
656 self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
657 }
658 (ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
659 }
660 ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
661 (ident, hir::ForeignItemKind::Type)
662 }
663 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
664 };
665
666 let item = hir::ForeignItem {
667 owner_id,
668 ident: self.lower_ident(*ident),
669 kind,
670 vis_span: self.lower_span(i.vis.span),
671 span: self.lower_span(i.span),
672 has_delayed_lints: !self.delayed_lints.is_empty(),
673 };
674 self.arena.alloc(item)
675 }
676
677 fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId {
678 hir::ForeignItemId { owner_id: self.owner_id(i.id) }
679 }
680
681 fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
682 let hir_id = self.lower_node_id(v.id);
683 self.lower_attrs(hir_id, &v.attrs, v.span, Target::Variant);
684 hir::Variant {
685 hir_id,
686 def_id: self.local_def_id(v.id),
687 data: self.lower_variant_data(hir_id, item_kind, &v.data),
688 disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
689 ident: self.lower_ident(v.ident),
690 span: self.lower_span(v.span),
691 }
692 }
693
694 fn lower_variant_data(
695 &mut self,
696 parent_id: hir::HirId,
697 item_kind: &ItemKind,
698 vdata: &VariantData,
699 ) -> hir::VariantData<'hir> {
700 match vdata {
701 VariantData::Struct { fields, recovered } => {
702 let fields = self
703 .arena
704 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
705
706 if let ItemKind::Union(..) = item_kind {
707 for field in &fields[..] {
708 if let Some(default) = field.default {
709 if self.tcx.features().default_field_values() {
713 self.dcx().emit_err(UnionWithDefault { span: default.span });
714 } else {
715 let _ = self.dcx().span_delayed_bug(
716 default.span,
717 "expected union default field values feature gate error but none \
718 was produced",
719 );
720 }
721 }
722 }
723 }
724
725 hir::VariantData::Struct { fields, recovered: *recovered }
726 }
727 VariantData::Tuple(fields, id) => {
728 let ctor_id = self.lower_node_id(*id);
729 self.alias_attrs(ctor_id, parent_id);
730 let fields = self
731 .arena
732 .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f)));
733 for field in &fields[..] {
734 if let Some(default) = field.default {
735 if self.tcx.features().default_field_values() {
740 self.dcx().emit_err(TupleStructWithDefault { span: default.span });
741 } else {
742 let _ = self.dcx().span_delayed_bug(
743 default.span,
744 "expected `default values on `struct` fields aren't supported` \
745 feature-gate error but none was produced",
746 );
747 }
748 }
749 }
750 hir::VariantData::Tuple(fields, ctor_id, self.local_def_id(*id))
751 }
752 VariantData::Unit(id) => {
753 let ctor_id = self.lower_node_id(*id);
754 self.alias_attrs(ctor_id, parent_id);
755 hir::VariantData::Unit(ctor_id, self.local_def_id(*id))
756 }
757 }
758 }
759
760 pub(super) fn lower_field_def(
761 &mut self,
762 (index, f): (usize, &FieldDef),
763 ) -> hir::FieldDef<'hir> {
764 let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
765 let hir_id = self.lower_node_id(f.id);
766 self.lower_attrs(hir_id, &f.attrs, f.span, Target::Field);
767 hir::FieldDef {
768 span: self.lower_span(f.span),
769 hir_id,
770 def_id: self.local_def_id(f.id),
771 ident: match f.ident {
772 Some(ident) => self.lower_ident(ident),
773 None => Ident::new(sym::integer(index), self.lower_span(f.span)),
775 },
776 vis_span: self.lower_span(f.vis.span),
777 default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
778 ty,
779 safety: self.lower_safety(f.safety, hir::Safety::Safe),
780 }
781 }
782
783 fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
784 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
785 let attrs = self.lower_attrs(
786 hir_id,
787 &i.attrs,
788 i.span,
789 Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait),
790 );
791 let trait_item_def_id = hir_id.expect_owner();
792
793 let (ident, generics, kind, has_default) = match &i.kind {
794 AssocItemKind::Const(box ConstItem {
795 ident, generics, ty, rhs, define_opaque, ..
796 }) => {
797 let (generics, kind) = self.lower_generics(
798 generics,
799 i.id,
800 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
801 |this| {
802 let ty = this
803 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
804 let rhs = rhs
805 .as_ref()
806 .map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span));
807 hir::TraitItemKind::Const(ty, rhs)
808 },
809 );
810
811 if define_opaque.is_some() {
812 if rhs.is_some() {
813 self.lower_define_opaque(hir_id, &define_opaque);
814 } else {
815 self.dcx().span_err(
816 i.span,
817 "only trait consts with default bodies can define opaque types",
818 );
819 }
820 }
821
822 (*ident, generics, kind, rhs.is_some())
823 }
824 AssocItemKind::Fn(box Fn {
825 sig, ident, generics, body: None, define_opaque, ..
826 }) => {
827 let idents = self.lower_fn_params_to_idents(&sig.decl);
830 let (generics, sig) = self.lower_method_sig(
831 generics,
832 sig,
833 i.id,
834 FnDeclKind::Trait,
835 sig.header.coroutine_kind,
836 attrs,
837 );
838 if define_opaque.is_some() {
839 self.dcx().span_err(
840 i.span,
841 "only trait methods with default bodies can define opaque types",
842 );
843 }
844 (
845 *ident,
846 generics,
847 hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(idents)),
848 false,
849 )
850 }
851 AssocItemKind::Fn(box Fn {
852 sig,
853 ident,
854 generics,
855 body: Some(body),
856 contract,
857 define_opaque,
858 ..
859 }) => {
860 let body_id = self.lower_maybe_coroutine_body(
861 sig.span,
862 i.span,
863 hir_id,
864 &sig.decl,
865 sig.header.coroutine_kind,
866 Some(body),
867 attrs,
868 contract.as_deref(),
869 );
870 let (generics, sig) = self.lower_method_sig(
871 generics,
872 sig,
873 i.id,
874 FnDeclKind::Trait,
875 sig.header.coroutine_kind,
876 attrs,
877 );
878 self.lower_define_opaque(hir_id, &define_opaque);
879 (
880 *ident,
881 generics,
882 hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
883 true,
884 )
885 }
886 AssocItemKind::Type(box TyAlias {
887 ident,
888 generics,
889 after_where_clause,
890 bounds,
891 ty,
892 ..
893 }) => {
894 let mut generics = generics.clone();
895 add_ty_alias_where_clause(&mut generics, after_where_clause, false);
896 let (generics, kind) = self.lower_generics(
897 &generics,
898 i.id,
899 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
900 |this| {
901 let ty = ty.as_ref().map(|x| {
902 this.lower_ty(
903 x,
904 ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
905 )
906 });
907 hir::TraitItemKind::Type(
908 this.lower_param_bounds(
909 bounds,
910 RelaxedBoundPolicy::Allowed,
911 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
912 ),
913 ty,
914 )
915 },
916 );
917 (*ident, generics, kind, ty.is_some())
918 }
919 AssocItemKind::Delegation(box delegation) => {
920 let delegation_results = self.lower_delegation(delegation, i.id, false);
921 let item_kind = hir::TraitItemKind::Fn(
922 delegation_results.sig,
923 hir::TraitFn::Provided(delegation_results.body_id),
924 );
925 (delegation.ident, delegation_results.generics, item_kind, true)
926 }
927 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
928 panic!("macros should have been expanded by now")
929 }
930 };
931
932 let item = hir::TraitItem {
933 owner_id: trait_item_def_id,
934 ident: self.lower_ident(ident),
935 generics,
936 kind,
937 span: self.lower_span(i.span),
938 defaultness: hir::Defaultness::Default { has_value: has_default },
939 has_delayed_lints: !self.delayed_lints.is_empty(),
940 };
941 self.arena.alloc(item)
942 }
943
944 fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId {
945 hir::TraitItemId { owner_id: self.owner_id(i.id) }
946 }
947
948 pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> {
950 self.expr(span, hir::ExprKind::Err(guar))
951 }
952
953 fn lower_trait_impl_header(
954 &mut self,
955 trait_impl_header: &TraitImplHeader,
956 ) -> &'hir hir::TraitImplHeader<'hir> {
957 let TraitImplHeader { constness, safety, polarity, defaultness, ref trait_ref } =
958 *trait_impl_header;
959 let constness = self.lower_constness(constness);
960 let safety = self.lower_safety(safety, hir::Safety::Safe);
961 let polarity = match polarity {
962 ImplPolarity::Positive => ImplPolarity::Positive,
963 ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
964 };
965 let has_val = true;
968 let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
969 let modifiers = TraitBoundModifiers {
970 constness: BoundConstness::Never,
971 asyncness: BoundAsyncness::Normal,
972 polarity: BoundPolarity::Positive,
974 };
975 let trait_ref = self.lower_trait_ref(
976 modifiers,
977 trait_ref,
978 ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
979 );
980
981 self.arena.alloc(hir::TraitImplHeader {
982 constness,
983 safety,
984 polarity,
985 defaultness,
986 defaultness_span,
987 trait_ref,
988 })
989 }
990
991 fn lower_impl_item(
992 &mut self,
993 i: &AssocItem,
994 is_in_trait_impl: bool,
995 ) -> &'hir hir::ImplItem<'hir> {
996 let has_value = true;
998 let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
999 let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
1000 let attrs = self.lower_attrs(
1001 hir_id,
1002 &i.attrs,
1003 i.span,
1004 Target::from_assoc_item_kind(&i.kind, AssocCtxt::Impl { of_trait: is_in_trait_impl }),
1005 );
1006
1007 let (ident, (generics, kind)) = match &i.kind {
1008 AssocItemKind::Const(box ConstItem {
1009 ident, generics, ty, rhs, define_opaque, ..
1010 }) => (
1011 *ident,
1012 self.lower_generics(
1013 generics,
1014 i.id,
1015 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1016 |this| {
1017 let ty = this
1018 .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
1019 this.lower_define_opaque(hir_id, &define_opaque);
1020 let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span);
1021 hir::ImplItemKind::Const(ty, rhs)
1022 },
1023 ),
1024 ),
1025 AssocItemKind::Fn(box Fn {
1026 sig,
1027 ident,
1028 generics,
1029 body,
1030 contract,
1031 define_opaque,
1032 ..
1033 }) => {
1034 let body_id = self.lower_maybe_coroutine_body(
1035 sig.span,
1036 i.span,
1037 hir_id,
1038 &sig.decl,
1039 sig.header.coroutine_kind,
1040 body.as_deref(),
1041 attrs,
1042 contract.as_deref(),
1043 );
1044 let (generics, sig) = self.lower_method_sig(
1045 generics,
1046 sig,
1047 i.id,
1048 if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
1049 sig.header.coroutine_kind,
1050 attrs,
1051 );
1052 self.lower_define_opaque(hir_id, &define_opaque);
1053
1054 (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id)))
1055 }
1056 AssocItemKind::Type(box TyAlias {
1057 ident, generics, after_where_clause, ty, ..
1058 }) => {
1059 let mut generics = generics.clone();
1060 add_ty_alias_where_clause(&mut generics, after_where_clause, false);
1061 (
1062 *ident,
1063 self.lower_generics(
1064 &generics,
1065 i.id,
1066 ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1067 |this| match ty {
1068 None => {
1069 let guar = this.dcx().span_delayed_bug(
1070 i.span,
1071 "expected to lower associated type, but it was missing",
1072 );
1073 let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar)));
1074 hir::ImplItemKind::Type(ty)
1075 }
1076 Some(ty) => {
1077 let ty = this.lower_ty(
1078 ty,
1079 ImplTraitContext::OpaqueTy {
1080 origin: hir::OpaqueTyOrigin::TyAlias {
1081 parent: this.local_def_id(i.id),
1082 in_assoc_ty: true,
1083 },
1084 },
1085 );
1086 hir::ImplItemKind::Type(ty)
1087 }
1088 },
1089 ),
1090 )
1091 }
1092 AssocItemKind::Delegation(box delegation) => {
1093 let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
1094 (
1095 delegation.ident,
1096 (
1097 delegation_results.generics,
1098 hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
1099 ),
1100 )
1101 }
1102 AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
1103 panic!("macros should have been expanded by now")
1104 }
1105 };
1106
1107 let span = self.lower_span(i.span);
1108 let item = hir::ImplItem {
1109 owner_id: hir_id.expect_owner(),
1110 ident: self.lower_ident(ident),
1111 generics,
1112 impl_kind: if is_in_trait_impl {
1113 ImplItemImplKind::Trait {
1114 defaultness,
1115 trait_item_def_id: self
1116 .resolver
1117 .get_partial_res(i.id)
1118 .and_then(|r| r.expect_full_res().opt_def_id())
1119 .ok_or_else(|| {
1120 self.dcx().span_delayed_bug(
1121 span,
1122 "could not resolve trait item being implemented",
1123 )
1124 }),
1125 }
1126 } else {
1127 ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
1128 },
1129 kind,
1130 span,
1131 has_delayed_lints: !self.delayed_lints.is_empty(),
1132 };
1133 self.arena.alloc(item)
1134 }
1135
1136 fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId {
1137 hir::ImplItemId { owner_id: self.owner_id(i.id) }
1138 }
1139
1140 fn lower_defaultness(
1141 &self,
1142 d: Defaultness,
1143 has_value: bool,
1144 ) -> (hir::Defaultness, Option<Span>) {
1145 match d {
1146 Defaultness::Default(sp) => {
1147 (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
1148 }
1149 Defaultness::Final => {
1150 assert!(has_value);
1151 (hir::Defaultness::Final, None)
1152 }
1153 }
1154 }
1155
1156 fn record_body(
1157 &mut self,
1158 params: &'hir [hir::Param<'hir>],
1159 value: hir::Expr<'hir>,
1160 ) -> hir::BodyId {
1161 let body = hir::Body { params, value: self.arena.alloc(value) };
1162 let id = body.id();
1163 assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
1164 self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
1165 id
1166 }
1167
1168 pub(super) fn lower_body(
1169 &mut self,
1170 f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
1171 ) -> hir::BodyId {
1172 let prev_coroutine_kind = self.coroutine_kind.take();
1173 let task_context = self.task_context.take();
1174 let (parameters, result) = f(self);
1175 let body_id = self.record_body(parameters, result);
1176 self.task_context = task_context;
1177 self.coroutine_kind = prev_coroutine_kind;
1178 body_id
1179 }
1180
1181 fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1182 let hir_id = self.lower_node_id(param.id);
1183 self.lower_attrs(hir_id, ¶m.attrs, param.span, Target::Param);
1184 hir::Param {
1185 hir_id,
1186 pat: self.lower_pat(¶m.pat),
1187 ty_span: self.lower_span(param.ty.span),
1188 span: self.lower_span(param.span),
1189 }
1190 }
1191
1192 pub(super) fn lower_fn_body(
1193 &mut self,
1194 decl: &FnDecl,
1195 contract: Option<&FnContract>,
1196 body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
1197 ) -> hir::BodyId {
1198 self.lower_body(|this| {
1199 let params =
1200 this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
1201
1202 if let Some(contract) = contract {
1204 (params, this.lower_contract(body, contract))
1205 } else {
1206 (params, body(this))
1207 }
1208 })
1209 }
1210
1211 fn lower_fn_body_block(
1212 &mut self,
1213 decl: &FnDecl,
1214 body: &Block,
1215 contract: Option<&FnContract>,
1216 ) -> hir::BodyId {
1217 self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
1218 }
1219
1220 pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1221 self.lower_body(|this| {
1222 (
1223 &[],
1224 match expr {
1225 Some(expr) => this.lower_expr_mut(expr),
1226 None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
1227 },
1228 )
1229 })
1230 }
1231
1232 fn lower_maybe_coroutine_body(
1235 &mut self,
1236 fn_decl_span: Span,
1237 span: Span,
1238 fn_id: hir::HirId,
1239 decl: &FnDecl,
1240 coroutine_kind: Option<CoroutineKind>,
1241 body: Option<&Block>,
1242 attrs: &'hir [hir::Attribute],
1243 contract: Option<&FnContract>,
1244 ) -> hir::BodyId {
1245 let Some(body) = body else {
1246 return self.lower_fn_body(decl, contract, |this| {
1250 if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
1251 || this.tcx.is_sdylib_interface_build()
1252 {
1253 let span = this.lower_span(span);
1254 let empty_block = hir::Block {
1255 hir_id: this.next_id(),
1256 stmts: &[],
1257 expr: None,
1258 rules: hir::BlockCheckMode::DefaultBlock,
1259 span,
1260 targeted_by_break: false,
1261 };
1262 let loop_ = hir::ExprKind::Loop(
1263 this.arena.alloc(empty_block),
1264 None,
1265 hir::LoopSource::Loop,
1266 span,
1267 );
1268 hir::Expr { hir_id: this.next_id(), kind: loop_, span }
1269 } else {
1270 this.expr_err(span, this.dcx().has_errors().unwrap())
1271 }
1272 });
1273 };
1274 let Some(coroutine_kind) = coroutine_kind else {
1275 return self.lower_fn_body_block(decl, body, contract);
1277 };
1278 self.lower_body(|this| {
1280 let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments(
1281 decl,
1282 |this| this.lower_block_expr(body),
1283 fn_decl_span,
1284 body.span,
1285 coroutine_kind,
1286 hir::CoroutineSource::Fn,
1287 );
1288
1289 let hir_id = expr.hir_id;
1291 this.maybe_forward_track_caller(body.span, fn_id, hir_id);
1292
1293 (parameters, expr)
1294 })
1295 }
1296
1297 pub(crate) fn lower_coroutine_body_with_moved_arguments(
1302 &mut self,
1303 decl: &FnDecl,
1304 lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>,
1305 fn_decl_span: Span,
1306 body_span: Span,
1307 coroutine_kind: CoroutineKind,
1308 coroutine_source: hir::CoroutineSource,
1309 ) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>) {
1310 let mut parameters: Vec<hir::Param<'_>> = Vec::new();
1311 let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
1312
1313 for (index, parameter) in decl.inputs.iter().enumerate() {
1346 let parameter = self.lower_param(parameter);
1347 let span = parameter.pat.span;
1348
1349 let (ident, is_simple_parameter) = match parameter.pat.kind {
1352 hir::PatKind::Binding(hir::BindingMode(ByRef::No, _), _, ident, _) => (ident, true),
1353 hir::PatKind::Binding(_, _, ident, _) => (ident, false),
1357 hir::PatKind::Wild => (Ident::with_dummy_span(rustc_span::kw::Underscore), false),
1358 _ => {
1359 let name = format!("__arg{index}");
1361 let ident = Ident::from_str(&name);
1362
1363 (ident, false)
1364 }
1365 };
1366
1367 let desugared_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1368
1369 let stmt_attrs = self.attrs.get(¶meter.hir_id.local_id).copied();
1375 let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident);
1376 let new_parameter = hir::Param {
1377 hir_id: parameter.hir_id,
1378 pat: new_parameter_pat,
1379 ty_span: self.lower_span(parameter.ty_span),
1380 span: self.lower_span(parameter.span),
1381 };
1382
1383 if is_simple_parameter {
1384 let expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1388 let stmt = self.stmt_let_pat(
1389 stmt_attrs,
1390 desugared_span,
1391 Some(expr),
1392 parameter.pat,
1393 hir::LocalSource::AsyncFn,
1394 );
1395 statements.push(stmt);
1396 } else {
1397 let (move_pat, move_id) =
1413 self.pat_ident_binding_mode(desugared_span, ident, hir::BindingMode::MUT);
1414 let move_expr = self.expr_ident(desugared_span, ident, new_parameter_id);
1415 let move_stmt = self.stmt_let_pat(
1416 None,
1417 desugared_span,
1418 Some(move_expr),
1419 move_pat,
1420 hir::LocalSource::AsyncFn,
1421 );
1422
1423 let pattern_expr = self.expr_ident(desugared_span, ident, move_id);
1426 let pattern_stmt = self.stmt_let_pat(
1427 stmt_attrs,
1428 desugared_span,
1429 Some(pattern_expr),
1430 parameter.pat,
1431 hir::LocalSource::AsyncFn,
1432 );
1433
1434 statements.push(move_stmt);
1435 statements.push(pattern_stmt);
1436 };
1437
1438 parameters.push(new_parameter);
1439 }
1440
1441 let mkbody = |this: &mut LoweringContext<'_, 'hir>| {
1442 let user_body = lower_body(this);
1444
1445 let desugared_span =
1447 this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
1448 let user_body = this.expr_drop_temps(desugared_span, this.arena.alloc(user_body));
1449
1450 let body = this.block_all(
1460 desugared_span,
1461 this.arena.alloc_from_iter(statements),
1462 Some(user_body),
1463 );
1464
1465 this.expr_block(body)
1466 };
1467 let desugaring_kind = match coroutine_kind {
1468 CoroutineKind::Async { .. } => hir::CoroutineDesugaring::Async,
1469 CoroutineKind::Gen { .. } => hir::CoroutineDesugaring::Gen,
1470 CoroutineKind::AsyncGen { .. } => hir::CoroutineDesugaring::AsyncGen,
1471 };
1472 let closure_id = coroutine_kind.closure_id();
1473
1474 let coroutine_expr = self.make_desugared_coroutine_expr(
1475 CaptureBy::Ref,
1480 closure_id,
1481 None,
1482 fn_decl_span,
1483 body_span,
1484 desugaring_kind,
1485 coroutine_source,
1486 mkbody,
1487 );
1488
1489 let expr = hir::Expr {
1490 hir_id: self.lower_node_id(closure_id),
1491 kind: coroutine_expr,
1492 span: self.lower_span(body_span),
1493 };
1494
1495 (self.arena.alloc_from_iter(parameters), expr)
1496 }
1497
1498 fn lower_method_sig(
1499 &mut self,
1500 generics: &Generics,
1501 sig: &FnSig,
1502 id: NodeId,
1503 kind: FnDeclKind,
1504 coroutine_kind: Option<CoroutineKind>,
1505 attrs: &[hir::Attribute],
1506 ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
1507 let header = self.lower_fn_header(sig.header, hir::Safety::Safe, attrs);
1508 let itctx = ImplTraitContext::Universal;
1509 let (generics, decl) = self.lower_generics(generics, id, itctx, |this| {
1510 this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
1511 });
1512 (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
1513 }
1514
1515 pub(super) fn lower_fn_header(
1516 &mut self,
1517 h: FnHeader,
1518 default_safety: hir::Safety,
1519 attrs: &[hir::Attribute],
1520 ) -> hir::FnHeader {
1521 let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
1522 hir::IsAsync::Async(self.lower_span(span))
1523 } else {
1524 hir::IsAsync::NotAsync
1525 };
1526
1527 let safety = self.lower_safety(h.safety, default_safety);
1528
1529 let safety = if find_attr!(attrs, AttributeKind::TargetFeature { was_forced: false, .. })
1531 && safety.is_safe()
1532 && !self.tcx.sess.target.is_like_wasm
1533 {
1534 hir::HeaderSafety::SafeTargetFeatures
1535 } else {
1536 safety.into()
1537 };
1538
1539 hir::FnHeader {
1540 safety,
1541 asyncness,
1542 constness: self.lower_constness(h.constness),
1543 abi: self.lower_extern(h.ext),
1544 }
1545 }
1546
1547 pub(super) fn lower_abi(&mut self, abi_str: StrLit) -> ExternAbi {
1548 let ast::StrLit { symbol_unescaped, span, .. } = abi_str;
1549 let extern_abi = symbol_unescaped.as_str().parse().unwrap_or_else(|_| {
1550 self.error_on_invalid_abi(abi_str);
1551 ExternAbi::Rust
1552 });
1553 let tcx = self.tcx;
1554
1555 if !tcx.sess.target.is_abi_supported(extern_abi) {
1557 let mut err = struct_span_code_err!(
1558 tcx.dcx(),
1559 span,
1560 E0570,
1561 "{extern_abi} is not a supported ABI for the current target",
1562 );
1563
1564 if let ExternAbi::Stdcall { unwind } = extern_abi {
1565 let c_abi = ExternAbi::C { unwind };
1566 let system_abi = ExternAbi::System { unwind };
1567 err.help(format!("if you need `extern {extern_abi}` on win32 and `extern {c_abi}` everywhere else, \
1568 use `extern {system_abi}`"
1569 ));
1570 }
1571 err.emit();
1572 }
1573 gate_unstable_abi(tcx.sess, tcx.features(), span, extern_abi);
1576 extern_abi
1577 }
1578
1579 pub(super) fn lower_extern(&mut self, ext: Extern) -> ExternAbi {
1580 match ext {
1581 Extern::None => ExternAbi::Rust,
1582 Extern::Implicit(_) => ExternAbi::FALLBACK,
1583 Extern::Explicit(abi, _) => self.lower_abi(abi),
1584 }
1585 }
1586
1587 fn error_on_invalid_abi(&self, abi: StrLit) {
1588 let abi_names = enabled_names(self.tcx.features(), abi.span)
1589 .iter()
1590 .map(|s| Symbol::intern(s))
1591 .collect::<Vec<_>>();
1592 let suggested_name = find_best_match_for_name(&abi_names, abi.symbol_unescaped, None);
1593 self.dcx().emit_err(InvalidAbi {
1594 abi: abi.symbol_unescaped,
1595 span: abi.span,
1596 suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
1597 span: abi.span,
1598 suggestion: suggested_name.to_string(),
1599 }),
1600 command: "rustc --print=calling-conventions".to_string(),
1601 });
1602 }
1603
1604 pub(super) fn lower_constness(&mut self, c: Const) -> hir::Constness {
1605 match c {
1606 Const::Yes(_) => hir::Constness::Const,
1607 Const::No => hir::Constness::NotConst,
1608 }
1609 }
1610
1611 pub(super) fn lower_safety(&self, s: Safety, default: hir::Safety) -> hir::Safety {
1612 match s {
1613 Safety::Unsafe(_) => hir::Safety::Unsafe,
1614 Safety::Default => default,
1615 Safety::Safe(_) => hir::Safety::Safe,
1616 }
1617 }
1618
1619 #[instrument(level = "debug", skip(self, f))]
1622 fn lower_generics<T>(
1623 &mut self,
1624 generics: &Generics,
1625 parent_node_id: NodeId,
1626 itctx: ImplTraitContext,
1627 f: impl FnOnce(&mut Self) -> T,
1628 ) -> (&'hir hir::Generics<'hir>, T) {
1629 assert!(self.impl_trait_defs.is_empty());
1630 assert!(self.impl_trait_bounds.is_empty());
1631
1632 let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
1633 predicates.extend(generics.params.iter().filter_map(|param| {
1634 self.lower_generic_bound_predicate(
1635 param.ident,
1636 param.id,
1637 ¶m.kind,
1638 ¶m.bounds,
1639 param.colon_span,
1640 generics.span,
1641 RelaxedBoundPolicy::Allowed,
1642 itctx,
1643 PredicateOrigin::GenericParam,
1644 )
1645 }));
1646 predicates.extend(
1647 generics
1648 .where_clause
1649 .predicates
1650 .iter()
1651 .map(|predicate| self.lower_where_predicate(predicate, &generics.params)),
1652 );
1653
1654 let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self
1655 .lower_generic_params_mut(&generics.params, hir::GenericParamSource::Generics)
1656 .collect();
1657
1658 let extra_lifetimes = self.resolver.extra_lifetime_params(parent_node_id);
1660 params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
1661 self.lifetime_res_to_generic_param(
1662 ident,
1663 node_id,
1664 res,
1665 hir::GenericParamSource::Generics,
1666 )
1667 }));
1668
1669 let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();
1670 let where_clause_span = self.lower_span(generics.where_clause.span);
1671 let span = self.lower_span(generics.span);
1672 let res = f(self);
1673
1674 let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
1675 params.extend(impl_trait_defs.into_iter());
1676
1677 let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
1678 predicates.extend(impl_trait_bounds.into_iter());
1679
1680 let lowered_generics = self.arena.alloc(hir::Generics {
1681 params: self.arena.alloc_from_iter(params),
1682 predicates: self.arena.alloc_from_iter(predicates),
1683 has_where_clause_predicates,
1684 where_clause_span,
1685 span,
1686 });
1687
1688 (lowered_generics, res)
1689 }
1690
1691 pub(super) fn lower_define_opaque(
1692 &mut self,
1693 hir_id: HirId,
1694 define_opaque: &Option<ThinVec<(NodeId, Path)>>,
1695 ) {
1696 assert_eq!(self.define_opaque, None);
1697 assert!(hir_id.is_owner());
1698 let Some(define_opaque) = define_opaque.as_ref() else {
1699 return;
1700 };
1701 let define_opaque = define_opaque.iter().filter_map(|(id, path)| {
1702 let res = self.resolver.get_partial_res(*id);
1703 let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else {
1704 self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
1705 return None;
1706 };
1707 let Some(did) = did.as_local() else {
1708 self.dcx().span_err(
1709 path.span,
1710 "only opaque types defined in the local crate can be defined",
1711 );
1712 return None;
1713 };
1714 Some((self.lower_span(path.span), did))
1715 });
1716 let define_opaque = self.arena.alloc_from_iter(define_opaque);
1717 self.define_opaque = Some(define_opaque);
1718 }
1719
1720 pub(super) fn lower_generic_bound_predicate(
1721 &mut self,
1722 ident: Ident,
1723 id: NodeId,
1724 kind: &GenericParamKind,
1725 bounds: &[GenericBound],
1726 colon_span: Option<Span>,
1727 parent_span: Span,
1728 rbp: RelaxedBoundPolicy<'_>,
1729 itctx: ImplTraitContext,
1730 origin: PredicateOrigin,
1731 ) -> Option<hir::WherePredicate<'hir>> {
1732 if bounds.is_empty() {
1734 return None;
1735 }
1736
1737 let bounds = self.lower_param_bounds(bounds, rbp, itctx);
1738
1739 let param_span = ident.span;
1740
1741 let span_start = colon_span.unwrap_or_else(|| param_span.shrink_to_hi());
1743 let span = bounds.iter().fold(span_start, |span_accum, bound| {
1744 match bound.span().find_ancestor_inside(parent_span) {
1745 Some(bound_span) => span_accum.to(bound_span),
1746 None => span_accum,
1747 }
1748 });
1749 let span = self.lower_span(span);
1750 let hir_id = self.next_id();
1751 let kind = self.arena.alloc(match kind {
1752 GenericParamKind::Const { .. } => return None,
1753 GenericParamKind::Type { .. } => {
1754 let def_id = self.local_def_id(id).to_def_id();
1755 let hir_id = self.next_id();
1756 let res = Res::Def(DefKind::TyParam, def_id);
1757 let ident = self.lower_ident(ident);
1758 let ty_path = self.arena.alloc(hir::Path {
1759 span: self.lower_span(param_span),
1760 res,
1761 segments: self
1762 .arena
1763 .alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
1764 });
1765 let ty_id = self.next_id();
1766 let bounded_ty =
1767 self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path));
1768 hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1769 bounded_ty: self.arena.alloc(bounded_ty),
1770 bounds,
1771 bound_generic_params: &[],
1772 origin,
1773 })
1774 }
1775 GenericParamKind::Lifetime => {
1776 let lt_id = self.next_node_id();
1777 let lifetime =
1778 self.new_named_lifetime(id, lt_id, ident, LifetimeSource::Other, ident.into());
1779 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1780 lifetime,
1781 bounds,
1782 in_where_clause: false,
1783 })
1784 }
1785 });
1786 Some(hir::WherePredicate { hir_id, span, kind })
1787 }
1788
1789 fn lower_where_predicate(
1790 &mut self,
1791 pred: &WherePredicate,
1792 params: &[ast::GenericParam],
1793 ) -> hir::WherePredicate<'hir> {
1794 let hir_id = self.lower_node_id(pred.id);
1795 let span = self.lower_span(pred.span);
1796 self.lower_attrs(hir_id, &pred.attrs, span, Target::WherePredicate);
1797 let kind = self.arena.alloc(match &pred.kind {
1798 WherePredicateKind::BoundPredicate(WhereBoundPredicate {
1799 bound_generic_params,
1800 bounded_ty,
1801 bounds,
1802 }) => {
1803 let rbp = if bound_generic_params.is_empty() {
1804 RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params)
1805 } else {
1806 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope)
1807 };
1808 hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1809 bound_generic_params: self.lower_generic_params(
1810 bound_generic_params,
1811 hir::GenericParamSource::Binder,
1812 ),
1813 bounded_ty: self.lower_ty(
1814 bounded_ty,
1815 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1816 ),
1817 bounds: self.lower_param_bounds(
1818 bounds,
1819 rbp,
1820 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1821 ),
1822 origin: PredicateOrigin::WhereClause,
1823 })
1824 }
1825 WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
1826 hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1827 lifetime: self.lower_lifetime(
1828 lifetime,
1829 LifetimeSource::Other,
1830 lifetime.ident.into(),
1831 ),
1832 bounds: self.lower_param_bounds(
1833 bounds,
1834 RelaxedBoundPolicy::Allowed,
1835 ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1836 ),
1837 in_where_clause: true,
1838 })
1839 }
1840 WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => {
1841 hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate {
1842 lhs_ty: self
1843 .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1844 rhs_ty: self
1845 .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
1846 })
1847 }
1848 });
1849 hir::WherePredicate { hir_id, span, kind }
1850 }
1851}