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