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