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