1use std::cell::Cell;
18use std::{assert_matches, debug_assert_matches, iter};
19
20use rustc_abi::{ExternAbi, Size};
21use rustc_ast::Recovered;
22use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
23use rustc_data_structures::thin_vec::{ThinVec, thin_vec};
24use rustc_errors::{
25 Applicability, Diag, DiagCtxtHandle, Diagnostic, E0228, ErrorGuaranteed, Level, StashKey,
26};
27use rustc_hir::def::DefKind;
28use rustc_hir::def_id::{DefId, LocalDefId};
29use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt};
30use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr};
31use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
32use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
33use rustc_middle::query::Providers;
34use rustc_middle::ty::util::{Discr, IntTypeExt};
35use rustc_middle::ty::{
36 self, AdtKind, Const, IsSuggestable, RegionExt, Ty, TyCtxt, TypeVisitableExt, TypingMode,
37 Unnormalized, fold_regions,
38};
39use rustc_middle::{bug, span_bug};
40use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
41use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
42use rustc_trait_selection::infer::InferCtxtExt;
43use rustc_trait_selection::traits::{
44 FulfillmentError, ObligationCtxt, hir_ty_lowering_dyn_compatibility_violations,
45};
46use tracing::{debug, instrument};
47
48use crate::diagnostics::{self, ElidedLifetimesAreNotAllowedInDelegations};
49use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason};
50
51mod clauses_of;
52pub(crate) mod dump;
53mod generics_of;
54mod item_bounds;
55mod resolve_bound_vars;
56mod type_of;
57
58pub(crate) fn provide(providers: &mut Providers) {
62 resolve_bound_vars::provide(providers);
63 *providers = Providers {
64 type_of: type_of::type_of,
65 type_of_opaque: type_of::type_of_opaque,
66 type_of_opaque_hir_typeck: type_of::type_of_opaque_hir_typeck,
67 type_alias_is_checked: type_of::type_alias_is_checked,
68 item_bounds: item_bounds::item_bounds,
69 explicit_item_bounds: item_bounds::explicit_item_bounds,
70 item_self_bounds: item_bounds::item_self_bounds,
71 explicit_item_self_bounds: item_bounds::explicit_item_self_bounds,
72 item_non_self_bounds: item_bounds::item_non_self_bounds,
73 impl_super_outlives: item_bounds::impl_super_outlives,
74 generics_of: generics_of::generics_of,
75 clauses_of: clauses_of::clauses_of,
76 explicit_clauses_of: clauses_of::explicit_clauses_of,
77 explicit_super_clauses_of: clauses_of::explicit_super_clauses_of,
78 explicit_implied_clauses_of: clauses_of::explicit_implied_clauses_of,
79 explicit_supertraits_containing_assoc_item:
80 clauses_of::explicit_supertraits_containing_assoc_item,
81 trait_explicit_clauses_and_bounds: clauses_of::trait_explicit_clauses_and_bounds,
82 const_conditions: clauses_of::const_conditions,
83 explicit_implied_const_bounds: clauses_of::explicit_implied_const_bounds,
84 type_param_clauses: clauses_of::type_param_clauses,
85 trait_def,
86 adt_def,
87 fn_sig,
88 impl_trait_header,
89 impl_is_fully_generic_for_reflection,
90 coroutine_kind,
91 coroutine_for_closure,
92 opaque_ty_origin,
93 rendered_precise_capturing_args,
94 const_param_default,
95 anon_const_kind,
96 const_of_item,
97 ..*providers
98 };
99}
100
101pub(crate) struct ItemCtxt<'tcx> {
131 tcx: TyCtxt<'tcx>,
132 item_def_id: LocalDefId,
133 tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
134 lowering_delegation_segment: bool,
135}
136
137#[derive(#[automatically_derived]
impl ::core::default::Default for HirPlaceholderCollector {
#[inline]
fn default() -> HirPlaceholderCollector {
HirPlaceholderCollector {
spans: ::core::default::Default::default(),
may_contain_const_infer: ::core::default::Default::default(),
}
}
}Default)]
140pub(crate) struct HirPlaceholderCollector {
141 pub spans: Vec<Span>,
142 pub may_contain_const_infer: bool,
145}
146
147impl<'v> Visitor<'v> for HirPlaceholderCollector {
148 fn visit_infer(&mut self, _inf_id: HirId, inf_span: Span, kind: InferKind<'v>) -> Self::Result {
149 self.spans.push(inf_span);
150
151 if let InferKind::Const(_) | InferKind::Ambig(_) = kind {
152 self.may_contain_const_infer = true;
153 }
154 }
155}
156
157fn placeholder_type_error_diag<'cx, 'tcx>(
158 cx: &'cx dyn HirTyLowerer<'tcx>,
159 generics: Option<&hir::Generics<'_>>,
160 placeholder_types: Vec<Span>,
161 additional_spans: Vec<Span>,
162 suggest: bool,
163 hir_ty: Option<&hir::Ty<'_>>,
164 kind: &'static str,
165) -> Diag<'cx> {
166 if placeholder_types.is_empty() {
167 return bad_placeholder(cx, additional_spans, kind);
168 }
169
170 let params = generics.map(|g| g.params).unwrap_or_default();
171 let type_name = params.next_type_param_name(None);
172 let mut sugg: Vec<_> =
173 placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
174
175 if let Some(generics) = generics {
176 if let Some(span) = params.iter().find_map(|arg| match arg.name {
177 hir::ParamName::Plain(Ident { name: kw::Underscore, span }) => Some(span),
178 _ => None,
179 }) {
180 sugg.push((span, (*type_name).to_string()));
183 } else if let Some(span) = generics.span_for_param_suggestion() {
184 sugg.push((span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(", {0}", type_name))
})format!(", {type_name}")));
186 } else {
187 sugg.push((generics.span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}>", type_name))
})format!("<{type_name}>")));
188 }
189 }
190
191 let mut err =
192 bad_placeholder(cx, placeholder_types.into_iter().chain(additional_spans).collect(), kind);
193
194 if suggest {
196 let mut is_fn = false;
197 let mut is_const_or_static = false;
198
199 if let Some(hir_ty) = hir_ty
200 && let hir::TyKind::FnPtr(_) = hir_ty.kind
201 {
202 is_fn = true;
203
204 is_const_or_static = #[allow(non_exhaustive_omitted_patterns)] match cx.tcx().parent_hir_node(hir_ty.hir_id)
{
Node::Item(&hir::Item {
kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..), .. }) |
Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Const(..),
.. }) |
Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), ..
}) => true,
_ => false,
}matches!(
206 cx.tcx().parent_hir_node(hir_ty.hir_id),
207 Node::Item(&hir::Item {
208 kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
209 ..
210 }) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
211 | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
212 );
213 }
214
215 if !(is_fn && is_const_or_static) {
218 err.multipart_suggestion(
219 "use type parameters instead",
220 sugg,
221 Applicability::HasPlaceholders,
222 );
223 }
224 }
225
226 err
227}
228
229fn bad_placeholder<'cx, 'tcx>(
233 cx: &'cx dyn HirTyLowerer<'tcx>,
234 mut spans: Vec<Span>,
235 kind: &'static str,
236) -> Diag<'cx> {
237 let kind = if kind.ends_with('s') { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}es", kind))
})format!("{kind}es") } else { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}s", kind))
})format!("{kind}s") };
238
239 spans.sort();
240 cx.dcx().create_err(diagnostics::PlaceholderNotAllowedItemSignatures { spans, kind })
241}
242
243impl<'tcx> ItemCtxt<'tcx> {
244 pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
245 ItemCtxt::new_internal(tcx, item_def_id, false)
246 }
247
248 fn new_internal(
249 tcx: TyCtxt<'tcx>,
250 item_def_id: LocalDefId,
251 delegation: bool,
252 ) -> ItemCtxt<'tcx> {
253 ItemCtxt {
254 tcx,
255 item_def_id,
256 tainted_by_errors: Cell::new(None),
257 lowering_delegation_segment: delegation,
258 }
259 }
260
261 pub(crate) fn new_for_delegation(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
262 ItemCtxt::new_internal(tcx, item_def_id, true)
263 }
264
265 pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
266 self.lowerer().lower_ty(hir_ty)
267 }
268
269 pub(crate) fn hir_id(&self) -> hir::HirId {
270 self.tcx.local_def_id_to_hir_id(self.item_def_id)
271 }
272
273 pub(crate) fn node(&self) -> hir::Node<'tcx> {
274 self.tcx.hir_node(self.hir_id())
275 }
276
277 fn check_tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
278 match self.tainted_by_errors.get() {
279 Some(err) => Err(err),
280 None => Ok(()),
281 }
282 }
283
284 fn report_placeholder_type_error(
285 &self,
286 placeholder_types: Vec<Span>,
287 infer_replacements: Vec<(Span, String)>,
288 ) -> ErrorGuaranteed {
289 let node = self.tcx.hir_node_by_def_id(self.item_def_id);
290 let generics = node.generics();
291 let kind_id = match node {
292 Node::GenericParam(_) | Node::WherePredicate(_) | Node::Field(_) => {
293 self.tcx.local_parent(self.item_def_id)
294 }
295 _ => self.item_def_id,
296 };
297 let kind = self.tcx.def_descr(kind_id.into());
298 let mut diag = placeholder_type_error_diag(
299 self,
300 generics,
301 placeholder_types,
302 infer_replacements.iter().map(|&(span, _)| span).collect(),
303 false,
304 None,
305 kind,
306 );
307 if !infer_replacements.is_empty() {
308 diag.multipart_suggestion(
309 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("try replacing `_` with the type{0} in the corresponding trait method signature",
if infer_replacements.len() == 1 { "" } else { "s" }))
})format!(
310 "try replacing `_` with the type{} in the corresponding trait method \
311 signature",
312 rustc_errors::pluralize!(infer_replacements.len()),
313 ),
314 infer_replacements,
315 Applicability::MachineApplicable,
316 );
317 }
318
319 diag.emit()
320 }
321}
322
323impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
324 fn tcx(&self) -> TyCtxt<'tcx> {
325 self.tcx
326 }
327
328 fn dcx(&self) -> DiagCtxtHandle<'_> {
329 self.tcx.dcx().taintable_handle(&self.tainted_by_errors)
330 }
331
332 fn item_def_id(&self) -> LocalDefId {
333 self.item_def_id
334 }
335
336 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
337 if let RegionInferReason::ObjectLifetimeDefault(sugg_sp) = reason {
338 let guar = self
341 .dcx()
342 .struct_span_err(
343 span,
344 "cannot deduce the lifetime bound for this trait object type from context",
345 )
346 .with_code(E0228)
347 .with_span_suggestion_verbose(
348 sugg_sp,
349 "please supply an explicit bound",
350 " + /* 'a */",
351 Applicability::HasPlaceholders,
352 )
353 .emit();
354 ty::Region::new_error(self.tcx(), guar)
355 } else {
356 if self.lowering_delegation_segment {
360 self.tcx.dcx().emit_err(ElidedLifetimesAreNotAllowedInDelegations { span });
361 }
362
363 ty::Region::new_error_with_message(self.tcx(), span, "inferred lifetime in signature")
365 }
366 }
367
368 fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
369 if !self.tcx.dcx().has_stashed_diagnostic(span, StashKey::ItemNoType) {
370 self.report_placeholder_type_error(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[span]))vec![span], ::alloc::vec::Vec::new()vec![]);
371 }
372 Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
373 }
374
375 fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
376 self.report_placeholder_type_error(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[span]))vec![span], ::alloc::vec::Vec::new()vec![]);
377 ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
378 }
379
380 fn register_trait_ascription_bounds(
381 &self,
382 _: Vec<(ty::Clause<'tcx>, Span)>,
383 _: HirId,
384 span: Span,
385 ) {
386 self.dcx().span_delayed_bug(span, "trait ascription type not allowed here");
387 }
388
389 fn probe_ty_param_bounds(
390 &self,
391 span: Span,
392 def_id: LocalDefId,
393 assoc_ident: Ident,
394 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
395 self.tcx.at(span).type_param_clauses((self.item_def_id, def_id, assoc_ident))
396 }
397
398 x;#[instrument(level = "debug", skip(self, _span), ret)]
399 fn select_inherent_assoc_candidates(
400 &self,
401 _span: Span,
402 self_ty: Ty<'tcx>,
403 candidates: Vec<InherentAssocCandidate>,
404 ) -> (Vec<InherentAssocCandidate>, ThinVec<FulfillmentError<'tcx>>) {
405 assert!(!self_ty.has_infer());
406
407 let self_ty = self.tcx.expand_free_alias_tys(self_ty);
412 debug!("select_inherent_assoc_candidates: self_ty={:?}", self_ty);
413
414 let candidates = candidates
415 .into_iter()
416 .filter(|&InherentAssocCandidate { impl_, .. }| {
417 let impl_ty = self.tcx().type_of(impl_).instantiate_identity().skip_norm_wip();
418
419 let impl_ty = self.tcx.expand_free_alias_tys(impl_ty);
421 debug!("select_inherent_assoc_candidates: impl_ty={:?}", impl_ty);
422
423 ty::DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify_with_depth(
440 self_ty,
441 impl_ty,
442 usize::MAX,
443 )
444 })
445 .collect();
446
447 (candidates, thin_vec![])
448 }
449
450 fn lower_assoc_item_path(
451 &self,
452 span: Span,
453 item_def_id: DefId,
454 item_segment: &rustc_hir::PathSegment<'tcx>,
455 poly_trait_ref: ty::PolyTraitRef<'tcx>,
456 ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
457 if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
458 let item_args = self.lowerer().lower_generic_args_of_assoc_item(
459 span,
460 item_def_id,
461 item_segment,
462 trait_ref.args,
463 );
464 Ok((item_def_id, item_args))
465 } else {
466 let (mut mpart_sugg, mut inferred_sugg) = (None, None);
468 let mut bound = String::new();
469
470 match self.node() {
471 hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
472 let item = self
473 .tcx
474 .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
475 match &item.kind {
476 hir::ItemKind::Enum(_, generics, _)
477 | hir::ItemKind::Struct(_, generics, _)
478 | hir::ItemKind::Union(_, generics, _) => {
479 let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
480 let (lt_sp, sugg) = match generics.params {
481 [] => (generics.span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("<{0}>", lt_name))
})format!("<{lt_name}>")),
482 [bound, ..] => (bound.span.shrink_to_lo(), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}, ", lt_name))
})format!("{lt_name}, ")),
483 };
484 mpart_sugg = Some(diagnostics::AssociatedItemTraitUninferredGenericParamsMultipartSuggestion {
485 fspan: lt_sp,
486 first: sugg,
487 sspan: span.with_hi(item_segment.ident.span.lo()),
488 second: ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}::",
self.tcx.instantiate_bound_regions_uncached(poly_trait_ref,
|_|
{
ty::Region::new_early_param(self.tcx,
ty::EarlyParamRegion {
index: 0,
name: Symbol::intern(<_name),
})
})))
})format!(
489 "{}::",
490 self.tcx.instantiate_bound_regions_uncached(
492 poly_trait_ref,
493 |_| {
494 ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
495 index: 0,
496 name: Symbol::intern(<_name),
497 })
498 }
499 ),
500 ),
501 });
502 }
503 _ => {}
504 }
505 }
506 hir::Node::Item(hir::Item {
507 kind:
508 hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..),
509 ..
510 }) => {}
511 hir::Node::Item(_)
512 | hir::Node::ForeignItem(_)
513 | hir::Node::TraitItem(_)
514 | hir::Node::ImplItem(_) => {
515 inferred_sugg = Some(span.with_hi(item_segment.ident.span.lo()));
516 bound = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}::",
self.tcx.anonymize_bound_vars(poly_trait_ref).skip_binder()))
})format!(
517 "{}::",
518 self.tcx.anonymize_bound_vars(poly_trait_ref).skip_binder(),
520 );
521 }
522 _ => {}
523 }
524
525 Err(self.tcx().dcx().emit_err(
526 diagnostics::AssociatedItemTraitUninferredGenericParams {
527 span,
528 inferred_sugg,
529 bound,
530 mpart_sugg,
531 what: self.tcx.def_descr(item_def_id),
532 },
533 ))
534 }
535 }
536
537 fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
538 ty.ty_adt_def()
540 }
541
542 fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
543 }
545
546 fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
547 None
548 }
549
550 fn lower_fn_sig(
551 &self,
552 decl: &hir::FnDecl<'tcx>,
553 _generics: Option<&hir::Generics<'_>>,
554 hir_id: rustc_hir::HirId,
555 _hir_ty: Option<&hir::Ty<'_>>,
556 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
557 let tcx = self.tcx();
558
559 let mut infer_replacements = ::alloc::vec::Vec::new()vec![];
560
561 let input_tys = decl
562 .inputs
563 .iter()
564 .enumerate()
565 .map(|(i, a)| {
566 if let hir::TyKind::Infer(()) = a.kind
567 && let Some(suggested_ty) =
568 self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
569 {
570 infer_replacements.push((a.span, suggested_ty.to_string()));
571 return Ty::new_error_with_message(tcx, a.span, suggested_ty.to_string());
572 }
573
574 self.lowerer().lower_ty(a)
575 })
576 .collect();
577
578 let output_ty = match decl.output {
579 hir::FnRetTy::Return(output) => {
580 if let hir::TyKind::Infer(()) = output.kind
581 && let Some(suggested_ty) =
582 self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
583 {
584 infer_replacements.push((output.span, suggested_ty.to_string()));
585 Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
586 } else {
587 self.lower_ty(output)
588 }
589 }
590 hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
591 };
592
593 if !infer_replacements.is_empty() {
594 self.report_placeholder_type_error(::alloc::vec::Vec::new()vec![], infer_replacements);
595 }
596 (input_tys, output_ty)
597 }
598
599 fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation> {
600 hir_ty_lowering_dyn_compatibility_violations(self.tcx, trait_def_id)
601 }
602}
603
604fn get_new_lifetime_name<'tcx>(
606 tcx: TyCtxt<'tcx>,
607 poly_trait_ref: ty::PolyTraitRef<'tcx>,
608 generics: &hir::Generics<'tcx>,
609) -> String {
610 let existing_lifetimes = tcx
611 .collect_referenced_late_bound_regions(poly_trait_ref)
612 .into_iter()
613 .filter_map(|lt| lt.get_name(tcx).map(|name| name.as_str().to_string()))
614 .chain(generics.params.iter().filter_map(|param| {
615 if let hir::GenericParamKind::Lifetime { .. } = ¶m.kind {
616 Some(param.name.ident().as_str().to_string())
617 } else {
618 None
619 }
620 }))
621 .collect::<FxHashSet<String>>();
622
623 let a_to_z_repeat_n = |n| {
624 (b'a'..=b'z').map(move |c| {
625 let mut s = '\''.to_string();
626 s.extend(std::iter::repeat_n(char::from(c), n));
627 s
628 })
629 };
630
631 (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
633}
634
635pub(super) fn check_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
636 tcx.ensure_ok().generics_of(def_id);
637 tcx.ensure_ok().type_of(def_id);
638 tcx.ensure_ok().clauses_of(def_id);
639}
640
641pub(super) fn check_enum_variant_types(tcx: TyCtxt<'_>, def_id: LocalDefId) {
642 struct ReprCIssue {
643 msg: &'static str,
644 }
645
646 impl<'a> Diagnostic<'a, ()> for ReprCIssue {
647 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
648 let Self { msg } = self;
649 Diag::new(dcx, level, msg)
650 .with_note("`repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C")
651 .with_help("use `repr($int_ty)` instead to explicitly set the size of this enum")
652 }
653 }
654
655 let def = tcx.adt_def(def_id);
656 let repr_type = def.repr().discr_type();
657 let initial = repr_type.initial_discriminant(tcx);
658 let mut prev_discr = None::<Discr<'_>>;
659 if !(tcx.sess.target.c_int_width < 128) {
::core::panicking::panic("assertion failed: tcx.sess.target.c_int_width < 128")
};assert!(tcx.sess.target.c_int_width < 128);
661 let mut min_discr = i128::MAX;
662 let mut max_discr = i128::MIN;
663
664 for variant in def.variants() {
666 let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
667 let cur_discr = if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr {
668 def.eval_explicit_discr(tcx, const_def_id).ok()
669 } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
670 Some(discr)
671 } else {
672 let span = tcx.def_span(variant.def_id);
673 tcx.dcx().emit_err(diagnostics::EnumDiscriminantOverflowed {
674 span,
675 discr: prev_discr.unwrap().to_string(),
676 item_name: tcx.item_ident(variant.def_id),
677 wrapped_discr: wrapped_discr.to_string(),
678 });
679 None
680 }
681 .unwrap_or(wrapped_discr);
682
683 if def.repr().c() {
684 let c_int = Size::from_bits(tcx.sess.target.c_int_width);
685 let c_uint_max = i128::try_from(c_int.unsigned_int_max()).unwrap();
686 let discr_size = cur_discr.ty.int_size_and_signed(tcx).0;
688 let discr_val = discr_size.sign_extend(cur_discr.val);
689 min_discr = min_discr.min(discr_val);
690 max_discr = max_discr.max(discr_val);
691
692 if !(min_discr >= c_int.signed_int_min() && max_discr <= c_int.signed_int_max())
694 && !(min_discr >= 0 && max_discr <= c_uint_max)
695 {
696 let span = tcx.def_span(variant.def_id);
697 let msg = if discr_val < c_int.signed_int_min() || discr_val > c_uint_max {
698 "`repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int`"
699 } else if discr_val < 0 {
700 "`repr(C)` enum discriminant does not fit into C `unsigned int`, and a previous discriminant does not fit into C `int`"
701 } else {
702 "`repr(C)` enum discriminant does not fit into C `int`, and a previous discriminant does not fit into C `unsigned int`"
703 };
704 tcx.emit_node_span_lint(
705 rustc_session::lint::builtin::REPR_C_ENUMS_LARGER_THAN_INT,
706 tcx.local_def_id_to_hir_id(def_id),
707 span,
708 ReprCIssue { msg },
709 );
710 }
711 }
712
713 prev_discr = Some(cur_discr);
714
715 for f in &variant.fields {
716 tcx.ensure_ok().generics_of(f.did);
717 tcx.ensure_ok().type_of(f.did);
718 tcx.ensure_ok().clauses_of(f.did);
719 }
720
721 if let Some(ctor_def_id) = variant.ctor_def_id() {
723 check_ctor(tcx, ctor_def_id.expect_local());
724 }
725 }
726}
727
728#[derive(#[automatically_derived]
impl ::core::clone::Clone for NestedSpan {
#[inline]
fn clone(&self) -> NestedSpan {
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NestedSpan { }Copy)]
729struct NestedSpan {
730 span: Span,
731 nested_field_span: Span,
732}
733
734impl NestedSpan {
735 fn to_field_already_declared_nested_help(&self) -> diagnostics::FieldAlreadyDeclaredNestedHelp {
736 diagnostics::FieldAlreadyDeclaredNestedHelp { span: self.span }
737 }
738}
739
740#[derive(#[automatically_derived]
impl ::core::clone::Clone for FieldDeclSpan {
#[inline]
fn clone(&self) -> FieldDeclSpan {
let _: ::core::clone::AssertParamIsClone<Span>;
let _: ::core::clone::AssertParamIsClone<NestedSpan>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FieldDeclSpan { }Copy)]
741enum FieldDeclSpan {
742 NotNested(Span),
743 Nested(NestedSpan),
744}
745
746impl From<Span> for FieldDeclSpan {
747 fn from(span: Span) -> Self {
748 Self::NotNested(span)
749 }
750}
751
752impl From<NestedSpan> for FieldDeclSpan {
753 fn from(span: NestedSpan) -> Self {
754 Self::Nested(span)
755 }
756}
757
758struct FieldUniquenessCheckContext<'tcx> {
759 tcx: TyCtxt<'tcx>,
760 seen_fields: FxIndexMap<Ident, FieldDeclSpan>,
761}
762
763impl<'tcx> FieldUniquenessCheckContext<'tcx> {
764 fn new(tcx: TyCtxt<'tcx>) -> Self {
765 Self { tcx, seen_fields: FxIndexMap::default() }
766 }
767
768 fn check_field_decl(&mut self, field_name: Ident, field_decl: FieldDeclSpan) {
770 use FieldDeclSpan::*;
771 let field_name = field_name.normalize_to_macros_2_0();
772 match (field_decl, self.seen_fields.get(&field_name).copied()) {
773 (NotNested(span), Some(NotNested(prev_span))) => {
774 self.tcx.dcx().emit_err(diagnostics::FieldAlreadyDeclared::NotNested {
775 field_name,
776 span,
777 prev_span,
778 });
779 }
780 (NotNested(span), Some(Nested(prev))) => {
781 self.tcx.dcx().emit_err(diagnostics::FieldAlreadyDeclared::PreviousNested {
782 field_name,
783 span,
784 prev_span: prev.span,
785 prev_nested_field_span: prev.nested_field_span,
786 prev_help: prev.to_field_already_declared_nested_help(),
787 });
788 }
789 (
790 Nested(current @ NestedSpan { span, nested_field_span, .. }),
791 Some(NotNested(prev_span)),
792 ) => {
793 self.tcx.dcx().emit_err(diagnostics::FieldAlreadyDeclared::CurrentNested {
794 field_name,
795 span,
796 nested_field_span,
797 help: current.to_field_already_declared_nested_help(),
798 prev_span,
799 });
800 }
801 (Nested(current @ NestedSpan { span, nested_field_span }), Some(Nested(prev))) => {
802 self.tcx.dcx().emit_err(diagnostics::FieldAlreadyDeclared::BothNested {
803 field_name,
804 span,
805 nested_field_span,
806 help: current.to_field_already_declared_nested_help(),
807 prev_span: prev.span,
808 prev_nested_field_span: prev.nested_field_span,
809 prev_help: prev.to_field_already_declared_nested_help(),
810 });
811 }
812 (field_decl, None) => {
813 self.seen_fields.insert(field_name, field_decl);
814 }
815 }
816 }
817}
818
819fn lower_variant<'tcx>(
820 tcx: TyCtxt<'tcx>,
821 variant_did: Option<LocalDefId>,
822 ident: Ident,
823 discr: ty::VariantDiscr,
824 def: &hir::VariantData<'tcx>,
825 adt_kind: ty::AdtKind,
826 parent_did: LocalDefId,
827) -> ty::VariantDef {
828 let mut field_uniqueness_check_ctx = FieldUniquenessCheckContext::new(tcx);
829 let fields = def
830 .fields()
831 .iter()
832 .inspect(|field| {
833 field_uniqueness_check_ctx.check_field_decl(field.ident, field.span.into());
834 })
835 .map(|f| ty::FieldDef {
836 did: f.def_id.to_def_id(),
837 name: f.ident.name,
838 vis: tcx.visibility(f.def_id),
839 mut_restriction: match f.mut_restriction.kind {
840 hir::RestrictionKind::Unrestricted => ty::RestrictionKind::Unrestricted,
841 hir::RestrictionKind::Restricted(path) => {
842 ty::RestrictionKind::Restricted(path.res, f.mut_restriction.span)
843 }
844 },
845 safety: f.safety,
846 value: f.default.map(|v| v.def_id.to_def_id()),
847 })
848 .collect();
849 let recovered = match def {
850 hir::VariantData::Struct { recovered: Recovered::Yes(guar), .. } => Some(*guar),
851 _ => None,
852 };
853 ty::VariantDef::new(
854 ident.name,
855 variant_did.map(LocalDefId::to_def_id),
856 def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())),
857 discr,
858 fields,
859 parent_did.to_def_id(),
860 recovered,
861 adt_kind == AdtKind::Struct && {
{
'done:
{
for i in
::rustc_attr_ir::HasAttrs::get_attrs(parent_did, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(NonExhaustive(..)) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(tcx, parent_did, NonExhaustive(..))
862 || variant_did
863 .is_some_and(|variant_did| {
{
'done:
{
for i in
::rustc_attr_ir::HasAttrs::get_attrs(variant_did, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(NonExhaustive(..)) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(tcx, variant_did, NonExhaustive(..))),
864 )
865}
866
867fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
868 use rustc_hir::*;
869
870 let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
871 ::rustc_middle::util::bug::bug_fmt(format_args!("expected ADT to be an item"));bug!("expected ADT to be an item");
872 };
873
874 let repr = tcx.repr_options_of_def(def_id);
875 let (kind, variants) = match &item.kind {
876 ItemKind::Enum(_, _, def) => {
877 let mut distance_from_explicit = 0;
878 let variants = def
879 .variants
880 .iter()
881 .map(|v| {
882 let discr = if let Some(e) = &v.disr_expr {
883 distance_from_explicit = 0;
884 ty::VariantDiscr::Explicit(e.def_id.to_def_id())
885 } else {
886 ty::VariantDiscr::Relative(distance_from_explicit)
887 };
888 distance_from_explicit += 1;
889
890 lower_variant(
891 tcx,
892 Some(v.def_id),
893 v.ident,
894 discr,
895 &v.data,
896 AdtKind::Enum,
897 def_id,
898 )
899 })
900 .collect();
901
902 (AdtKind::Enum, variants)
903 }
904 ItemKind::Struct(ident, _, def) | ItemKind::Union(ident, _, def) => {
905 let adt_kind = match item.kind {
906 ItemKind::Struct(..) => AdtKind::Struct,
907 _ => AdtKind::Union,
908 };
909 let variants = std::iter::once(lower_variant(
910 tcx,
911 None,
912 *ident,
913 ty::VariantDiscr::Relative(0),
914 def,
915 adt_kind,
916 def_id,
917 ))
918 .collect();
919
920 (adt_kind, variants)
921 }
922 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("{0:?} is not an ADT",
item.owner_id.def_id))bug!("{:?} is not an ADT", item.owner_id.def_id),
923 };
924 tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
925}
926
927fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
928 let item = tcx.hir_expect_item(def_id);
929
930 let (constness, is_alias, is_auto, safety, impl_restriction) = match item.kind {
931 hir::ItemKind::Trait { impl_restriction, constness, is_auto, safety, .. } => (
932 constness,
933 false,
934 is_auto == hir::IsAuto::Yes,
935 safety,
936 match impl_restriction.kind {
937 hir::RestrictionKind::Restricted(path) => {
938 ty::RestrictionKind::Restricted(path.res, impl_restriction.span)
939 }
940 hir::RestrictionKind::Unrestricted => ty::RestrictionKind::Unrestricted,
941 },
942 ),
943 hir::ItemKind::TraitAlias(constness, ..) => {
944 (constness, true, false, hir::Safety::Safe, ty::RestrictionKind::Unrestricted)
945 }
946 _ => ::rustc_middle::util::bug::span_bug_fmt(item.span,
format_args!("trait_def_of_item invoked on non-trait"))span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
947 };
948
949 #[allow(deprecated)]
951 let attrs = tcx.get_all_attrs(def_id);
952
953 let paren_sugar = {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcParenSugar) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcParenSugar);
954
955 let is_marker = !is_alias && {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(Marker) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, Marker);
957
958 let rustc_coinductive = {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcCoinductive) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcCoinductive);
959 let is_fundamental = {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(Fundamental) => {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, Fundamental);
960
961 let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcSkipDuringMethodDispatch {
array, boxed_slice }) => {
break 'done Some([*array, *boxed_slice]);
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(
962 attrs,
963 RustcSkipDuringMethodDispatch { array, boxed_slice } => [*array, *boxed_slice]
964 )
965 .unwrap_or([false; 2]);
966
967 let specialization_kind = if {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcAllowLifetimeDependentSpecialization)
=> {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcAllowLifetimeDependentSpecialization) {
968 ty::trait_def::TraitSpecializationKind::Marker
969 } else if {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcSpecializationTrait)
=> {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcSpecializationTrait) {
970 ty::trait_def::TraitSpecializationKind::AlwaysApplicable
971 } else {
972 ty::trait_def::TraitSpecializationKind::None
973 };
974
975 let must_implement_one_of = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcMustImplementOneOf {
fn_names, .. }) => {
break 'done
Some(fn_names.iter().cloned().collect::<Box<[_]>>());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(
976 attrs,
977 RustcMustImplementOneOf { fn_names, .. } =>
978 fn_names
979 .iter()
980 .cloned()
981 .collect::<Box<[_]>>()
982 );
983
984 let deny_explicit_impl = {
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcDenyExplicitImpl) =>
{
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, RustcDenyExplicitImpl);
985 let force_dyn_incompatible = {
'done:
{
for i in attrs {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcDynIncompatibleTrait(span))
=> {
break 'done Some(*span);
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(attrs, RustcDynIncompatibleTrait(span) => *span);
986
987 ty::TraitDef {
988 def_id: def_id.to_def_id(),
989 impl_restriction,
990 safety,
991 constness,
992 paren_sugar,
993 has_auto_impl: is_auto,
994 is_marker,
995 is_coinductive: rustc_coinductive || is_auto,
996 is_fundamental,
997 skip_array_during_method_dispatch,
998 skip_boxed_slice_during_method_dispatch,
999 specialization_kind,
1000 must_implement_one_of,
1001 force_dyn_incompatible,
1002 deny_explicit_impl,
1003 }
1004}
1005
1006x;#[instrument(level = "debug", skip(tcx), ret)]
1007fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
1008 use rustc_hir::Node::*;
1009 use rustc_hir::*;
1010
1011 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1012
1013 let icx = ItemCtxt::new(tcx, def_id);
1014
1015 let output = match tcx.hir_node(hir_id) {
1016 TraitItem(hir::TraitItem {
1017 kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
1018 generics,
1019 ..
1020 })
1021 | Item(hir::Item { kind: ItemKind::Fn { sig, generics, .. }, .. }) => {
1022 lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1023 }
1024
1025 ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
1026 if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
1028 && i.of_trait.is_some()
1029 {
1030 icx.lowerer().lower_fn_ty(
1031 hir_id,
1032 sig.header.safety(),
1033 sig.header.abi,
1034 sig.decl,
1035 Some(generics),
1036 None,
1037 )
1038 } else {
1039 lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1040 }
1041 }
1042
1043 TraitItem(hir::TraitItem {
1044 kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
1045 generics,
1046 ..
1047 }) => icx.lowerer().lower_fn_ty(
1048 hir_id,
1049 header.safety(),
1050 header.abi,
1051 decl,
1052 Some(generics),
1053 None,
1054 ),
1055
1056 ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
1057 let abi = tcx.hir_get_foreign_abi(hir_id);
1058 compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
1059 }
1060
1061 Ctor(data) => {
1062 assert_matches!(data.ctor(), Some(_));
1063 let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id();
1064 let ty = tcx.type_of(adt_def_id).instantiate_identity().skip_norm_wip();
1065 let inputs = data
1066 .fields()
1067 .iter()
1068 .map(|f| tcx.type_of(f.def_id).instantiate_identity().skip_norm_wip());
1069 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(inputs, ty, hir::Safety::Safe))
1070 }
1071
1072 Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
1073 bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
1084 }
1085
1086 x => {
1087 bug!("unexpected sort of node in fn_sig(): {:?}", x);
1088 }
1089 };
1090 ty::EarlyBinder::bind(tcx, output)
1091}
1092
1093fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
1094 icx: &ItemCtxt<'tcx>,
1095 sig: &'tcx hir::FnSig<'tcx>,
1096 generics: &'tcx hir::Generics<'tcx>,
1097 def_id: LocalDefId,
1098) -> ty::PolyFnSig<'tcx> {
1099 if let Some(infer_ret_ty) = sig.decl.output.is_suggestable_infer_ty() {
1100 return recover_infer_ret_ty(icx, infer_ret_ty, generics, def_id);
1101 }
1102
1103 icx.lowerer().lower_fn_ty(
1104 icx.tcx().local_def_id_to_hir_id(def_id),
1105 sig.header.safety(),
1106 sig.header.abi,
1107 sig.decl,
1108 Some(generics),
1109 None,
1110 )
1111}
1112
1113fn late_param_regions_to_bound<'tcx, T>(
1115 tcx: TyCtxt<'tcx>,
1116 scope: DefId,
1117 bound_vars: &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
1118 value: T,
1119) -> ty::Binder<'tcx, T>
1120where
1121 T: ty::TypeFoldable<TyCtxt<'tcx>>,
1122{
1123 let value = fold_regions(tcx, value, |r, debruijn| match r.kind() {
1124 ty::ReLateParam(lp) => {
1125 {
match (&lp.scope, &scope) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(lp.scope, scope);
1127
1128 let br = match lp.kind {
1129 kind @ (ty::LateParamRegionKind::Anon(idx)
1131 | ty::LateParamRegionKind::NamedAnon(idx, _)) => {
1132 let idx = idx as usize;
1133 let var = ty::BoundVar::from_usize(idx);
1134
1135 let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied()
1136 else {
1137 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected late-bound region {0:?} for bound vars {1:?}",
kind, bound_vars));bug!("unexpected late-bound region {kind:?} for bound vars {bound_vars:?}");
1138 };
1139
1140 ty::BoundRegion { var, kind }
1141 }
1142
1143 ty::LateParamRegionKind::Named(def_id) => bound_vars
1145 .iter()
1146 .enumerate()
1147 .find_map(|(idx, bv)| match bv {
1148 ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did))
1149 if did == def_id =>
1150 {
1151 Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1152 }
1153 _ => None,
1154 })
1155 .unwrap(),
1156
1157 ty::LateParamRegionKind::ClosureEnv => bound_vars
1158 .iter()
1159 .enumerate()
1160 .find_map(|(idx, bv)| match bv {
1161 ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => {
1162 Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1163 }
1164 _ => None,
1165 })
1166 .unwrap(),
1167 };
1168
1169 ty::Region::new_bound(tcx, debruijn, br)
1170 }
1171 _ => r,
1172 });
1173
1174 ty::Binder::bind_with_vars(value, bound_vars)
1175}
1176
1177fn recover_infer_ret_ty<'tcx>(
1178 icx: &ItemCtxt<'tcx>,
1179 infer_ret_ty: &'tcx hir::Ty<'tcx>,
1180 generics: &'tcx hir::Generics<'tcx>,
1181 def_id: LocalDefId,
1182) -> ty::PolyFnSig<'tcx> {
1183 let tcx = icx.tcx;
1184 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1185
1186 let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
1187
1188 let has_region_params = generics.params.iter().any(|param| match param.kind {
1193 GenericParamKind::Lifetime { .. } => true,
1194 _ => false,
1195 });
1196 let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() {
1197 ty::ReErased => {
1198 if has_region_params {
1199 ty::Region::new_error_with_message(
1200 tcx,
1201 DUMMY_SP,
1202 "erased region is not allowed here in return type",
1203 )
1204 } else {
1205 tcx.lifetimes.re_static
1206 }
1207 }
1208 _ => r,
1209 });
1210
1211 let mut visitor = HirPlaceholderCollector::default();
1212 visitor.visit_ty_unambig(infer_ret_ty);
1213
1214 let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
1215 let ret_ty = fn_sig.output();
1216
1217 let mut recovered_ret_ty = None;
1221 if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
1222 diag.span_suggestion_verbose(
1223 infer_ret_ty.span,
1224 "replace with the correct return type",
1225 suggestable_ret_ty,
1226 Applicability::MachineApplicable,
1227 );
1228 recovered_ret_ty = Some(suggestable_ret_ty);
1229 } else if let Some(sugg) = suggest_impl_trait(
1230 &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
1231 tcx.param_env(def_id),
1232 ret_ty,
1233 ) {
1234 diag.span_suggestion_verbose(
1235 infer_ret_ty.span,
1236 "replace with an appropriate return type",
1237 sugg,
1238 Applicability::MachineApplicable,
1239 );
1240 } else if ret_ty.is_closure() {
1241 diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1242 }
1243
1244 if ret_ty.is_closure() {
1246 diag.note(
1247 "for more information on `Fn` traits and closure types, see \
1248 https://doc.rust-lang.org/book/ch13-01-closures.html",
1249 );
1250 }
1251 let guar = diag.emit();
1252
1253 let bound_vars = tcx.late_bound_vars(hir_id);
1257 let scope = def_id.to_def_id();
1258
1259 let fn_sig = tcx.mk_fn_sig(
1260 fn_sig.inputs().iter().copied(),
1261 recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
1262 fn_sig.fn_sig_kind,
1263 );
1264
1265 late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig)
1266}
1267
1268pub fn suggest_impl_trait<'tcx>(
1269 infcx: &InferCtxt<'tcx>,
1270 param_env: ty::ParamEnv<'tcx>,
1271 ret_ty: Ty<'tcx>,
1272) -> Option<String> {
1273 let format_as_assoc: fn(_, _, _, _, _) -> _ =
1274 |tcx: TyCtxt<'tcx>,
1275 _: ty::GenericArgsRef<'tcx>,
1276 trait_def_id: DefId,
1277 assoc_item_def_id: DefId,
1278 item_ty: Ty<'tcx>| {
1279 let trait_name = tcx.item_name(trait_def_id);
1280 let assoc_name = tcx.item_name(assoc_item_def_id);
1281 Some(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("impl {0}<{1} = {2}>", trait_name,
assoc_name, item_ty))
})format!("impl {trait_name}<{assoc_name} = {item_ty}>"))
1282 };
1283 let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
1284 |tcx: TyCtxt<'tcx>,
1285 args: ty::GenericArgsRef<'tcx>,
1286 trait_def_id: DefId,
1287 _: DefId,
1288 item_ty: Ty<'tcx>| {
1289 let trait_name = tcx.item_name(trait_def_id);
1290 let args_tuple = args.type_at(1);
1291 let ty::Tuple(types) = *args_tuple.kind() else {
1292 return None;
1293 };
1294 let types = types.make_suggestable(tcx, false, None)?;
1295 let maybe_ret =
1296 if item_ty.is_unit() { String::new() } else { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" -> {0}", item_ty))
})format!(" -> {item_ty}") };
1297 Some(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("impl {1}({0}){2}",
types.iter().map(|ty|
ty.to_string()).collect::<Vec<_>>().join(", "), trait_name,
maybe_ret))
})format!(
1298 "impl {trait_name}({}){maybe_ret}",
1299 types.iter().map(|ty| ty.to_string()).collect::<Vec<_>>().join(", ")
1300 ))
1301 };
1302
1303 for (trait_def_id, assoc_item_def_id, formatter) in [
1304 (
1305 infcx.tcx.get_diagnostic_item(sym::Iterator),
1306 infcx.tcx.get_diagnostic_item(sym::IteratorItem),
1307 format_as_assoc,
1308 ),
1309 (
1310 infcx.tcx.lang_items().future_trait(),
1311 infcx.tcx.lang_items().future_output(),
1312 format_as_assoc,
1313 ),
1314 (
1315 infcx.tcx.lang_items().async_fn_trait(),
1316 infcx.tcx.lang_items().async_fn_once_output(),
1317 format_as_parenthesized,
1318 ),
1319 (
1320 infcx.tcx.lang_items().async_fn_mut_trait(),
1321 infcx.tcx.lang_items().async_fn_once_output(),
1322 format_as_parenthesized,
1323 ),
1324 (
1325 infcx.tcx.lang_items().async_fn_once_trait(),
1326 infcx.tcx.lang_items().async_fn_once_output(),
1327 format_as_parenthesized,
1328 ),
1329 (
1330 infcx.tcx.lang_items().fn_trait(),
1331 infcx.tcx.lang_items().fn_once_output(),
1332 format_as_parenthesized,
1333 ),
1334 (
1335 infcx.tcx.lang_items().fn_mut_trait(),
1336 infcx.tcx.lang_items().fn_once_output(),
1337 format_as_parenthesized,
1338 ),
1339 (
1340 infcx.tcx.lang_items().fn_once_trait(),
1341 infcx.tcx.lang_items().fn_once_output(),
1342 format_as_parenthesized,
1343 ),
1344 ] {
1345 let Some(trait_def_id) = trait_def_id else {
1346 continue;
1347 };
1348 let Some(assoc_item_def_id) = assoc_item_def_id else {
1349 continue;
1350 };
1351 if infcx.tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
1352 continue;
1353 }
1354 let sugg = infcx.probe(|_| {
1355 let args = ty::GenericArgs::for_item(infcx.tcx, trait_def_id, |param, _| {
1356 if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(DUMMY_SP, param) }
1357 });
1358 if !infcx
1359 .type_implements_trait(trait_def_id, args, param_env)
1360 .must_apply_modulo_regions()
1361 {
1362 return None;
1363 }
1364 let ocx = ObligationCtxt::new(&infcx);
1365 let item_ty = ocx.normalize(
1366 &ObligationCause::dummy(),
1367 param_env,
1368 Unnormalized::new(Ty::new_projection_from_args(
1369 infcx.tcx,
1370 ty::IsRigid::No,
1371 assoc_item_def_id,
1372 args,
1373 )),
1374 );
1375 if ocx.try_evaluate_obligations().no_errors()
1377 && let item_ty = infcx.resolve_vars_if_possible(item_ty)
1378 && let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None)
1379 && let Some(sugg) = formatter(
1380 infcx.tcx,
1381 infcx.resolve_vars_if_possible(args),
1382 trait_def_id,
1383 assoc_item_def_id,
1384 item_ty,
1385 )
1386 {
1387 return Some(sugg);
1388 }
1389
1390 None
1391 });
1392
1393 if sugg.is_some() {
1394 return sugg;
1395 }
1396 }
1397 None
1398}
1399
1400fn impl_is_fully_generic_for_reflection(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
1401 tcx.impl_trait_header(def_id).is_fully_generic_for_reflection()
1402 && tcx.explicit_clauses_of(def_id).is_fully_generic_for_reflection()
1403}
1404
1405fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> {
1406 let icx = ItemCtxt::new(tcx, def_id);
1407 let item = tcx.hir_expect_item(def_id);
1408 let impl_ = item.expect_impl();
1409 let of_trait = impl_
1410 .of_trait
1411 .unwrap_or_else(|| {
::core::panicking::panic_fmt(format_args!("expected impl trait, found inherent impl on {0:?}",
def_id));
}panic!("expected impl trait, found inherent impl on {def_id:?}"));
1412 let selfty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
1413 let is_rustc_reservation = {
{
'done:
{
for i in ::rustc_attr_ir::HasAttrs::get_attrs(def_id, &tcx) {
#[allow(unused_imports)]
use ::rustc_attr_ir::AttributeKind::*;
let i: &::rustc_attr_ir::Attribute = i;
match i {
::rustc_attr_ir::Attribute::Parsed(RustcReservationImpl(..))
=> {
break 'done Some(());
}
::rustc_attr_ir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(tcx, def_id, RustcReservationImpl(..));
1414
1415 check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);
1416
1417 let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty);
1418
1419 ty::ImplTraitHeader {
1420 trait_ref: ty::EarlyBinder::bind(tcx, trait_ref),
1421 safety: of_trait.safety,
1422 polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation),
1423 constness: impl_.constness,
1424 }
1425}
1426
1427fn check_impl_constness(
1428 tcx: TyCtxt<'_>,
1429 constness: hir::Constness,
1430 hir_trait_ref: &hir::TraitRef<'_>,
1431) {
1432 if let hir::Constness::NotConst = constness {
1433 return;
1434 }
1435
1436 let Some(trait_def_id) = hir_trait_ref.trait_def_id() else { return };
1437 if tcx.is_const_trait(trait_def_id) {
1438 return;
1439 }
1440
1441 let trait_name = tcx.item_name(trait_def_id).to_string();
1442 let (suggestion, suggestion_pre) = match (trait_def_id.as_local(), tcx.sess.is_nightly_build())
1443 {
1444 (Some(trait_def_id), true) => {
1445 let span = tcx.hir_expect_item(trait_def_id).vis_span;
1446 let span = tcx.sess.source_map().span_extend_while_whitespace(span);
1447
1448 (
1449 Some(span.shrink_to_hi()),
1450 if tcx.features().const_trait_impl() {
1451 ""
1452 } else {
1453 "enable `#![feature(const_trait_impl)]` in your crate and "
1454 },
1455 )
1456 }
1457 (None, _) | (_, false) => (None, ""),
1458 };
1459 tcx.dcx().emit_err(diagnostics::ConstImplForNonConstTrait {
1460 trait_ref_span: hir_trait_ref.path.span,
1461 trait_name,
1462 suggestion,
1463 suggestion_pre,
1464 marking: (),
1465 adding: (),
1466 });
1467}
1468
1469fn polarity_of_impl(
1470 tcx: TyCtxt<'_>,
1471 of_trait: &hir::TraitImplHeader<'_>,
1472 is_rustc_reservation: bool,
1473) -> ty::ImplPolarity {
1474 match of_trait.polarity {
1475 hir::ImplPolarity::Negative(span) => {
1476 if is_rustc_reservation {
1477 let span = span.to(of_trait.trait_ref.path.span);
1478 tcx.dcx().span_err(span, "reservation impls can't be negative");
1479 }
1480 ty::ImplPolarity::Negative
1481 }
1482 hir::ImplPolarity::Positive => {
1483 if is_rustc_reservation {
1484 ty::ImplPolarity::Reservation
1485 } else {
1486 ty::ImplPolarity::Positive
1487 }
1488 }
1489 }
1490}
1491
1492fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1498 tcx: TyCtxt<'tcx>,
1499 generics: &'a hir::Generics<'a>,
1500) -> impl Iterator<Item = &'a hir::GenericParam<'a>> {
1501 generics.params.iter().filter(move |param| match param.kind {
1502 GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
1503 _ => false,
1504 })
1505}
1506
1507fn compute_sig_of_foreign_fn_decl<'tcx>(
1508 tcx: TyCtxt<'tcx>,
1509 def_id: LocalDefId,
1510 decl: &'tcx hir::FnDecl<'tcx>,
1511 abi: ExternAbi,
1512 safety: hir::Safety,
1513) -> ty::PolyFnSig<'tcx> {
1514 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1515 let fty =
1516 ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
1517
1518 if !tcx.features().simd_ffi() {
1521 let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
1522 if ty.is_simd() {
1523 let snip = tcx
1524 .sess
1525 .source_map()
1526 .span_to_snippet(hir_ty.span)
1527 .map_or_else(|_| String::new(), |s| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" `{0}`", s))
})format!(" `{s}`"));
1528 tcx.dcx()
1529 .emit_err(diagnostics::SIMDFFIHighlyExperimental { span: hir_ty.span, snip });
1530 }
1531 };
1532 for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
1533 check(input, *ty)
1534 }
1535 if let hir::FnRetTy::Return(ty) = decl.output {
1536 check(ty, fty.output().skip_binder())
1537 }
1538 }
1539
1540 fty
1541}
1542
1543fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
1544 match tcx.hir_node_by_def_id(def_id) {
1545 Node::Expr(&hir::Expr {
1546 kind:
1547 hir::ExprKind::Closure(&rustc_hir::Closure {
1548 kind: hir::ClosureKind::Coroutine(kind),
1549 ..
1550 }),
1551 ..
1552 }) => Some(kind),
1553 _ => None,
1554 }
1555}
1556
1557fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
1558 let &rustc_hir::Closure { kind: hir::ClosureKind::CoroutineClosure(_), body, .. } =
1559 tcx.hir_node_by_def_id(def_id).expect_closure()
1560 else {
1561 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!()
1562 };
1563
1564 let &hir::Expr {
1565 kind:
1566 hir::ExprKind::Closure(&rustc_hir::Closure {
1567 def_id,
1568 kind: hir::ClosureKind::Coroutine(_),
1569 ..
1570 }),
1571 ..
1572 } = tcx.hir_body(body).value
1573 else {
1574 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!()
1575 };
1576
1577 def_id.to_def_id()
1578}
1579
1580fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueTyOrigin<DefId> {
1581 match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
1582 hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl } => {
1583 hir::OpaqueTyOrigin::FnReturn { parent: parent.to_def_id(), in_trait_or_impl }
1584 }
1585 hir::OpaqueTyOrigin::AsyncFn { parent, in_trait_or_impl } => {
1586 hir::OpaqueTyOrigin::AsyncFn { parent: parent.to_def_id(), in_trait_or_impl }
1587 }
1588 hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty } => {
1589 hir::OpaqueTyOrigin::TyAlias { parent: parent.to_def_id(), in_assoc_ty }
1590 }
1591 }
1592}
1593
1594fn rendered_precise_capturing_args<'tcx>(
1595 tcx: TyCtxt<'tcx>,
1596 def_id: LocalDefId,
1597) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
1598 if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
1599 tcx.opt_rpitit_info(def_id.to_def_id())
1600 {
1601 return tcx.rendered_precise_capturing_args(opaque_def_id);
1602 }
1603
1604 tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
1605 hir::GenericBound::Use(args, ..) => {
1606 Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg {
1607 PreciseCapturingArgKind::Lifetime(_) => {
1608 PreciseCapturingArgKind::Lifetime(arg.name())
1609 }
1610 PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()),
1611 })))
1612 }
1613 _ => None,
1614 })
1615}
1616
1617fn const_param_default<'tcx>(
1618 tcx: TyCtxt<'tcx>,
1619 local_def_id: LocalDefId,
1620) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1621 let hir::Node::GenericParam(hir::GenericParam {
1622 kind: hir::GenericParamKind::Const { default: Some(default_ct), .. },
1623 ..
1624 }) = tcx.hir_node_by_def_id(local_def_id)
1625 else {
1626 ::rustc_middle::util::bug::span_bug_fmt(tcx.def_span(local_def_id),
format_args!("`const_param_default` expected a generic parameter with a constant"))span_bug!(
1627 tcx.def_span(local_def_id),
1628 "`const_param_default` expected a generic parameter with a constant"
1629 )
1630 };
1631
1632 let icx = ItemCtxt::new(tcx, local_def_id);
1633
1634 let def_id = local_def_id.to_def_id();
1635 let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id));
1636
1637 let ct = icx.lowerer().lower_const_arg(
1638 default_ct,
1639 tcx.type_of(def_id).instantiate(tcx, identity_args).skip_norm_wip(),
1640 );
1641 ty::EarlyBinder::bind(tcx, ct)
1642}
1643
1644fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKind {
1645 if true {
{
match tcx.def_kind(def) {
DefKind::AnonConst => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"DefKind::AnonConst", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(tcx.def_kind(def), DefKind::AnonConst);
1646 let hir_id = tcx.local_def_id_to_hir_id(def);
1647 let parent_node_id = tcx.parent_hir_id(hir_id);
1648 match tcx.hir_node(parent_node_id) {
1649 hir::Node::ConstArg(const_arg) => {
1650 if true {
{
match const_arg.kind {
hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) if
*def_id == def => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) if *def_id == def",
::core::option::Option::None);
}
}
};
};debug_assert_matches!(const_arg.kind, hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) if *def_id == def);
1651 if tcx.features().generic_const_exprs() {
1652 ty::AnonConstKind::GCE
1653 } else if tcx.features().min_generic_const_args() {
1654 ty::AnonConstKind::MCG
1655 } else if let hir::Node::Expr(hir::Expr {
1656 kind: hir::ExprKind::Repeat(_, repeat_count),
1657 ..
1658 }) = tcx.parent_hir_node(parent_node_id)
1659 && repeat_count.hir_id == parent_node_id
1660 {
1661 ty::AnonConstKind::RepeatExprCount
1662 } else {
1663 ty::AnonConstKind::MCG
1664 }
1665 }
1666 hir::Node::Expr(hir::Expr {
1667 kind: hir::ExprKind::ConstBlock(..) | hir::ExprKind::InlineAsm(..),
1668 ..
1669 }) => ty::AnonConstKind::NonTypeSystemInline,
1670 _ => ty::AnonConstKind::NonTypeSystemAnon,
1671 }
1672}
1673
1674x;#[instrument(level = "debug", skip(tcx), ret)]
1675fn const_of_item<'tcx>(
1676 tcx: TyCtxt<'tcx>,
1677 def_id: LocalDefId,
1678) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1679 let ct_rhs = match tcx.hir_node_by_def_id(def_id) {
1680 hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => *ct,
1681 hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(_, ct), .. }) => {
1682 ct.expect("no default value for trait assoc const")
1683 }
1684 hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => *ct,
1685 _ => {
1686 span_bug!(tcx.def_span(def_id), "`const_of_item` expected a const or assoc const item")
1687 }
1688 };
1689 let ct_arg = match ct_rhs {
1690 hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg,
1691 hir::ConstItemRhs::Body(_) => {
1692 let e = tcx.dcx().span_delayed_bug(
1693 tcx.def_span(def_id),
1694 "cannot call const_of_item on a non-type_const",
1695 );
1696 return ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e));
1697 }
1698 };
1699 let icx = ItemCtxt::new(tcx, def_id);
1700 let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
1701 let ct = icx.lowerer().lower_const_arg(
1702 ct_arg,
1703 tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args).skip_norm_wip(),
1704 );
1705 if let Err(e) = icx.check_tainted_by_errors()
1706 && !ct.references_error()
1707 {
1708 ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e))
1709 } else {
1710 ty::EarlyBinder::bind(tcx, ct)
1711 }
1712}