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 safety: f.safety,
839 value: f.default.map(|v| v.def_id.to_def_id()),
840 })
841 .collect();
842 let recovered = match def {
843 hir::VariantData::Struct { recovered: Recovered::Yes(guar), .. } => Some(*guar),
844 _ => None,
845 };
846 ty::VariantDef::new(
847 ident.name,
848 variant_did.map(LocalDefId::to_def_id),
849 def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())),
850 discr,
851 fields,
852 parent_did.to_def_id(),
853 recovered,
854 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(..))
855 || variant_did
856 .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(..))),
857 )
858}
859
860fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
861 use rustc_hir::*;
862
863 let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
864 ::rustc_middle::util::bug::bug_fmt(format_args!("expected ADT to be an item"));bug!("expected ADT to be an item");
865 };
866
867 let repr = tcx.repr_options_of_def(def_id);
868 let (kind, variants) = match &item.kind {
869 ItemKind::Enum(_, _, def) => {
870 let mut distance_from_explicit = 0;
871 let variants = def
872 .variants
873 .iter()
874 .map(|v| {
875 let discr = if let Some(e) = &v.disr_expr {
876 distance_from_explicit = 0;
877 ty::VariantDiscr::Explicit(e.def_id.to_def_id())
878 } else {
879 ty::VariantDiscr::Relative(distance_from_explicit)
880 };
881 distance_from_explicit += 1;
882
883 lower_variant(
884 tcx,
885 Some(v.def_id),
886 v.ident,
887 discr,
888 &v.data,
889 AdtKind::Enum,
890 def_id,
891 )
892 })
893 .collect();
894
895 (AdtKind::Enum, variants)
896 }
897 ItemKind::Struct(ident, _, def) | ItemKind::Union(ident, _, def) => {
898 let adt_kind = match item.kind {
899 ItemKind::Struct(..) => AdtKind::Struct,
900 _ => AdtKind::Union,
901 };
902 let variants = std::iter::once(lower_variant(
903 tcx,
904 None,
905 *ident,
906 ty::VariantDiscr::Relative(0),
907 def,
908 adt_kind,
909 def_id,
910 ))
911 .collect();
912
913 (adt_kind, variants)
914 }
915 _ => ::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),
916 };
917 tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
918}
919
920fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
921 let item = tcx.hir_expect_item(def_id);
922
923 let (constness, is_alias, is_auto, safety, impl_restriction) = match item.kind {
924 hir::ItemKind::Trait { impl_restriction, constness, is_auto, safety, .. } => (
925 constness,
926 false,
927 is_auto == hir::IsAuto::Yes,
928 safety,
929 if let hir::RestrictionKind::Restricted(path) = impl_restriction.kind {
930 ty::trait_def::ImplRestrictionKind::Restricted(path.res, impl_restriction.span)
931 } else {
932 ty::trait_def::ImplRestrictionKind::Unrestricted
933 },
934 ),
935 hir::ItemKind::TraitAlias(constness, ..) => (
936 constness,
937 true,
938 false,
939 hir::Safety::Safe,
940 ty::trait_def::ImplRestrictionKind::Unrestricted,
941 ),
942 _ => ::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"),
943 };
944
945 #[allow(deprecated)]
947 let attrs = tcx.get_all_attrs(def_id);
948
949 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);
950
951 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);
953
954 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);
955 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);
956
957 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!(
958 attrs,
959 RustcSkipDuringMethodDispatch { array, boxed_slice } => [*array, *boxed_slice]
960 )
961 .unwrap_or([false; 2]);
962
963 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) {
964 ty::trait_def::TraitSpecializationKind::Marker
965 } 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) {
966 ty::trait_def::TraitSpecializationKind::AlwaysApplicable
967 } else {
968 ty::trait_def::TraitSpecializationKind::None
969 };
970
971 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!(
972 attrs,
973 RustcMustImplementOneOf { fn_names, .. } =>
974 fn_names
975 .iter()
976 .cloned()
977 .collect::<Box<[_]>>()
978 );
979
980 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);
981 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);
982
983 ty::TraitDef {
984 def_id: def_id.to_def_id(),
985 impl_restriction,
986 safety,
987 constness,
988 paren_sugar,
989 has_auto_impl: is_auto,
990 is_marker,
991 is_coinductive: rustc_coinductive || is_auto,
992 is_fundamental,
993 skip_array_during_method_dispatch,
994 skip_boxed_slice_during_method_dispatch,
995 specialization_kind,
996 must_implement_one_of,
997 force_dyn_incompatible,
998 deny_explicit_impl,
999 }
1000}
1001
1002x;#[instrument(level = "debug", skip(tcx), ret)]
1003fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
1004 use rustc_hir::Node::*;
1005 use rustc_hir::*;
1006
1007 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1008
1009 let icx = ItemCtxt::new(tcx, def_id);
1010
1011 let output = match tcx.hir_node(hir_id) {
1012 TraitItem(hir::TraitItem {
1013 kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
1014 generics,
1015 ..
1016 })
1017 | Item(hir::Item { kind: ItemKind::Fn { sig, generics, .. }, .. }) => {
1018 lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1019 }
1020
1021 ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
1022 if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
1024 && i.of_trait.is_some()
1025 {
1026 icx.lowerer().lower_fn_ty(
1027 hir_id,
1028 sig.header.safety(),
1029 sig.header.abi,
1030 sig.decl,
1031 Some(generics),
1032 None,
1033 )
1034 } else {
1035 lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1036 }
1037 }
1038
1039 TraitItem(hir::TraitItem {
1040 kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
1041 generics,
1042 ..
1043 }) => icx.lowerer().lower_fn_ty(
1044 hir_id,
1045 header.safety(),
1046 header.abi,
1047 decl,
1048 Some(generics),
1049 None,
1050 ),
1051
1052 ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
1053 let abi = tcx.hir_get_foreign_abi(hir_id);
1054 compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
1055 }
1056
1057 Ctor(data) => {
1058 assert_matches!(data.ctor(), Some(_));
1059 let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id();
1060 let ty = tcx.type_of(adt_def_id).instantiate_identity().skip_norm_wip();
1061 let inputs = data
1062 .fields()
1063 .iter()
1064 .map(|f| tcx.type_of(f.def_id).instantiate_identity().skip_norm_wip());
1065 ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(inputs, ty, hir::Safety::Safe))
1066 }
1067
1068 Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
1069 bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
1080 }
1081
1082 x => {
1083 bug!("unexpected sort of node in fn_sig(): {:?}", x);
1084 }
1085 };
1086 ty::EarlyBinder::bind(tcx, output)
1087}
1088
1089fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
1090 icx: &ItemCtxt<'tcx>,
1091 sig: &'tcx hir::FnSig<'tcx>,
1092 generics: &'tcx hir::Generics<'tcx>,
1093 def_id: LocalDefId,
1094) -> ty::PolyFnSig<'tcx> {
1095 if let Some(infer_ret_ty) = sig.decl.output.is_suggestable_infer_ty() {
1096 return recover_infer_ret_ty(icx, infer_ret_ty, generics, def_id);
1097 }
1098
1099 icx.lowerer().lower_fn_ty(
1100 icx.tcx().local_def_id_to_hir_id(def_id),
1101 sig.header.safety(),
1102 sig.header.abi,
1103 sig.decl,
1104 Some(generics),
1105 None,
1106 )
1107}
1108
1109fn late_param_regions_to_bound<'tcx, T>(
1111 tcx: TyCtxt<'tcx>,
1112 scope: DefId,
1113 bound_vars: &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
1114 value: T,
1115) -> ty::Binder<'tcx, T>
1116where
1117 T: ty::TypeFoldable<TyCtxt<'tcx>>,
1118{
1119 let value = fold_regions(tcx, value, |r, debruijn| match r.kind() {
1120 ty::ReLateParam(lp) => {
1121 {
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);
1123
1124 let br = match lp.kind {
1125 kind @ (ty::LateParamRegionKind::Anon(idx)
1127 | ty::LateParamRegionKind::NamedAnon(idx, _)) => {
1128 let idx = idx as usize;
1129 let var = ty::BoundVar::from_usize(idx);
1130
1131 let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied()
1132 else {
1133 ::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:?}");
1134 };
1135
1136 ty::BoundRegion { var, kind }
1137 }
1138
1139 ty::LateParamRegionKind::Named(def_id) => bound_vars
1141 .iter()
1142 .enumerate()
1143 .find_map(|(idx, bv)| match bv {
1144 ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did))
1145 if did == def_id =>
1146 {
1147 Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1148 }
1149 _ => None,
1150 })
1151 .unwrap(),
1152
1153 ty::LateParamRegionKind::ClosureEnv => bound_vars
1154 .iter()
1155 .enumerate()
1156 .find_map(|(idx, bv)| match bv {
1157 ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => {
1158 Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1159 }
1160 _ => None,
1161 })
1162 .unwrap(),
1163 };
1164
1165 ty::Region::new_bound(tcx, debruijn, br)
1166 }
1167 _ => r,
1168 });
1169
1170 ty::Binder::bind_with_vars(value, bound_vars)
1171}
1172
1173fn recover_infer_ret_ty<'tcx>(
1174 icx: &ItemCtxt<'tcx>,
1175 infer_ret_ty: &'tcx hir::Ty<'tcx>,
1176 generics: &'tcx hir::Generics<'tcx>,
1177 def_id: LocalDefId,
1178) -> ty::PolyFnSig<'tcx> {
1179 let tcx = icx.tcx;
1180 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1181
1182 let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
1183
1184 let has_region_params = generics.params.iter().any(|param| match param.kind {
1189 GenericParamKind::Lifetime { .. } => true,
1190 _ => false,
1191 });
1192 let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() {
1193 ty::ReErased => {
1194 if has_region_params {
1195 ty::Region::new_error_with_message(
1196 tcx,
1197 DUMMY_SP,
1198 "erased region is not allowed here in return type",
1199 )
1200 } else {
1201 tcx.lifetimes.re_static
1202 }
1203 }
1204 _ => r,
1205 });
1206
1207 let mut visitor = HirPlaceholderCollector::default();
1208 visitor.visit_ty_unambig(infer_ret_ty);
1209
1210 let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
1211 let ret_ty = fn_sig.output();
1212
1213 let mut recovered_ret_ty = None;
1217 if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
1218 diag.span_suggestion_verbose(
1219 infer_ret_ty.span,
1220 "replace with the correct return type",
1221 suggestable_ret_ty,
1222 Applicability::MachineApplicable,
1223 );
1224 recovered_ret_ty = Some(suggestable_ret_ty);
1225 } else if let Some(sugg) = suggest_impl_trait(
1226 &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
1227 tcx.param_env(def_id),
1228 ret_ty,
1229 ) {
1230 diag.span_suggestion_verbose(
1231 infer_ret_ty.span,
1232 "replace with an appropriate return type",
1233 sugg,
1234 Applicability::MachineApplicable,
1235 );
1236 } else if ret_ty.is_closure() {
1237 diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1238 }
1239
1240 if ret_ty.is_closure() {
1242 diag.note(
1243 "for more information on `Fn` traits and closure types, see \
1244 https://doc.rust-lang.org/book/ch13-01-closures.html",
1245 );
1246 }
1247 let guar = diag.emit();
1248
1249 let bound_vars = tcx.late_bound_vars(hir_id);
1253 let scope = def_id.to_def_id();
1254
1255 let fn_sig = tcx.mk_fn_sig(
1256 fn_sig.inputs().iter().copied(),
1257 recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
1258 fn_sig.fn_sig_kind,
1259 );
1260
1261 late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig)
1262}
1263
1264pub fn suggest_impl_trait<'tcx>(
1265 infcx: &InferCtxt<'tcx>,
1266 param_env: ty::ParamEnv<'tcx>,
1267 ret_ty: Ty<'tcx>,
1268) -> Option<String> {
1269 let format_as_assoc: fn(_, _, _, _, _) -> _ =
1270 |tcx: TyCtxt<'tcx>,
1271 _: ty::GenericArgsRef<'tcx>,
1272 trait_def_id: DefId,
1273 assoc_item_def_id: DefId,
1274 item_ty: Ty<'tcx>| {
1275 let trait_name = tcx.item_name(trait_def_id);
1276 let assoc_name = tcx.item_name(assoc_item_def_id);
1277 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}>"))
1278 };
1279 let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
1280 |tcx: TyCtxt<'tcx>,
1281 args: ty::GenericArgsRef<'tcx>,
1282 trait_def_id: DefId,
1283 _: DefId,
1284 item_ty: Ty<'tcx>| {
1285 let trait_name = tcx.item_name(trait_def_id);
1286 let args_tuple = args.type_at(1);
1287 let ty::Tuple(types) = *args_tuple.kind() else {
1288 return None;
1289 };
1290 let types = types.make_suggestable(tcx, false, None)?;
1291 let maybe_ret =
1292 if item_ty.is_unit() { String::new() } else { ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" -> {0}", item_ty))
})format!(" -> {item_ty}") };
1293 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!(
1294 "impl {trait_name}({}){maybe_ret}",
1295 types.iter().map(|ty| ty.to_string()).collect::<Vec<_>>().join(", ")
1296 ))
1297 };
1298
1299 for (trait_def_id, assoc_item_def_id, formatter) in [
1300 (
1301 infcx.tcx.get_diagnostic_item(sym::Iterator),
1302 infcx.tcx.get_diagnostic_item(sym::IteratorItem),
1303 format_as_assoc,
1304 ),
1305 (
1306 infcx.tcx.lang_items().future_trait(),
1307 infcx.tcx.lang_items().future_output(),
1308 format_as_assoc,
1309 ),
1310 (
1311 infcx.tcx.lang_items().async_fn_trait(),
1312 infcx.tcx.lang_items().async_fn_once_output(),
1313 format_as_parenthesized,
1314 ),
1315 (
1316 infcx.tcx.lang_items().async_fn_mut_trait(),
1317 infcx.tcx.lang_items().async_fn_once_output(),
1318 format_as_parenthesized,
1319 ),
1320 (
1321 infcx.tcx.lang_items().async_fn_once_trait(),
1322 infcx.tcx.lang_items().async_fn_once_output(),
1323 format_as_parenthesized,
1324 ),
1325 (
1326 infcx.tcx.lang_items().fn_trait(),
1327 infcx.tcx.lang_items().fn_once_output(),
1328 format_as_parenthesized,
1329 ),
1330 (
1331 infcx.tcx.lang_items().fn_mut_trait(),
1332 infcx.tcx.lang_items().fn_once_output(),
1333 format_as_parenthesized,
1334 ),
1335 (
1336 infcx.tcx.lang_items().fn_once_trait(),
1337 infcx.tcx.lang_items().fn_once_output(),
1338 format_as_parenthesized,
1339 ),
1340 ] {
1341 let Some(trait_def_id) = trait_def_id else {
1342 continue;
1343 };
1344 let Some(assoc_item_def_id) = assoc_item_def_id else {
1345 continue;
1346 };
1347 if infcx.tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
1348 continue;
1349 }
1350 let sugg = infcx.probe(|_| {
1351 let args = ty::GenericArgs::for_item(infcx.tcx, trait_def_id, |param, _| {
1352 if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(DUMMY_SP, param) }
1353 });
1354 if !infcx
1355 .type_implements_trait(trait_def_id, args, param_env)
1356 .must_apply_modulo_regions()
1357 {
1358 return None;
1359 }
1360 let ocx = ObligationCtxt::new(&infcx);
1361 let item_ty = ocx.normalize(
1362 &ObligationCause::dummy(),
1363 param_env,
1364 Unnormalized::new(Ty::new_projection_from_args(
1365 infcx.tcx,
1366 ty::IsRigid::No,
1367 assoc_item_def_id,
1368 args,
1369 )),
1370 );
1371 if ocx.try_evaluate_obligations().is_empty()
1373 && let item_ty = infcx.resolve_vars_if_possible(item_ty)
1374 && let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None)
1375 && let Some(sugg) = formatter(
1376 infcx.tcx,
1377 infcx.resolve_vars_if_possible(args),
1378 trait_def_id,
1379 assoc_item_def_id,
1380 item_ty,
1381 )
1382 {
1383 return Some(sugg);
1384 }
1385
1386 None
1387 });
1388
1389 if sugg.is_some() {
1390 return sugg;
1391 }
1392 }
1393 None
1394}
1395
1396fn impl_is_fully_generic_for_reflection(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
1397 tcx.impl_trait_header(def_id).is_fully_generic_for_reflection()
1398 && tcx.explicit_clauses_of(def_id).is_fully_generic_for_reflection()
1399}
1400
1401fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> {
1402 let icx = ItemCtxt::new(tcx, def_id);
1403 let item = tcx.hir_expect_item(def_id);
1404 let impl_ = item.expect_impl();
1405 let of_trait = impl_
1406 .of_trait
1407 .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:?}"));
1408 let selfty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
1409 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(..));
1410
1411 check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);
1412
1413 let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty);
1414
1415 ty::ImplTraitHeader {
1416 trait_ref: ty::EarlyBinder::bind(tcx, trait_ref),
1417 safety: of_trait.safety,
1418 polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation),
1419 constness: impl_.constness,
1420 }
1421}
1422
1423fn check_impl_constness(
1424 tcx: TyCtxt<'_>,
1425 constness: hir::Constness,
1426 hir_trait_ref: &hir::TraitRef<'_>,
1427) {
1428 if let hir::Constness::NotConst = constness {
1429 return;
1430 }
1431
1432 let Some(trait_def_id) = hir_trait_ref.trait_def_id() else { return };
1433 if tcx.is_const_trait(trait_def_id) {
1434 return;
1435 }
1436
1437 let trait_name = tcx.item_name(trait_def_id).to_string();
1438 let (suggestion, suggestion_pre) = match (trait_def_id.as_local(), tcx.sess.is_nightly_build())
1439 {
1440 (Some(trait_def_id), true) => {
1441 let span = tcx.hir_expect_item(trait_def_id).vis_span;
1442 let span = tcx.sess.source_map().span_extend_while_whitespace(span);
1443
1444 (
1445 Some(span.shrink_to_hi()),
1446 if tcx.features().const_trait_impl() {
1447 ""
1448 } else {
1449 "enable `#![feature(const_trait_impl)]` in your crate and "
1450 },
1451 )
1452 }
1453 (None, _) | (_, false) => (None, ""),
1454 };
1455 tcx.dcx().emit_err(diagnostics::ConstImplForNonConstTrait {
1456 trait_ref_span: hir_trait_ref.path.span,
1457 trait_name,
1458 suggestion,
1459 suggestion_pre,
1460 marking: (),
1461 adding: (),
1462 });
1463}
1464
1465fn polarity_of_impl(
1466 tcx: TyCtxt<'_>,
1467 of_trait: &hir::TraitImplHeader<'_>,
1468 is_rustc_reservation: bool,
1469) -> ty::ImplPolarity {
1470 match of_trait.polarity {
1471 hir::ImplPolarity::Negative(span) => {
1472 if is_rustc_reservation {
1473 let span = span.to(of_trait.trait_ref.path.span);
1474 tcx.dcx().span_err(span, "reservation impls can't be negative");
1475 }
1476 ty::ImplPolarity::Negative
1477 }
1478 hir::ImplPolarity::Positive => {
1479 if is_rustc_reservation {
1480 ty::ImplPolarity::Reservation
1481 } else {
1482 ty::ImplPolarity::Positive
1483 }
1484 }
1485 }
1486}
1487
1488fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1494 tcx: TyCtxt<'tcx>,
1495 generics: &'a hir::Generics<'a>,
1496) -> impl Iterator<Item = &'a hir::GenericParam<'a>> {
1497 generics.params.iter().filter(move |param| match param.kind {
1498 GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
1499 _ => false,
1500 })
1501}
1502
1503fn compute_sig_of_foreign_fn_decl<'tcx>(
1504 tcx: TyCtxt<'tcx>,
1505 def_id: LocalDefId,
1506 decl: &'tcx hir::FnDecl<'tcx>,
1507 abi: ExternAbi,
1508 safety: hir::Safety,
1509) -> ty::PolyFnSig<'tcx> {
1510 let hir_id = tcx.local_def_id_to_hir_id(def_id);
1511 let fty =
1512 ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
1513
1514 if !tcx.features().simd_ffi() {
1517 let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
1518 if ty.is_simd() {
1519 let snip = tcx
1520 .sess
1521 .source_map()
1522 .span_to_snippet(hir_ty.span)
1523 .map_or_else(|_| String::new(), |s| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" `{0}`", s))
})format!(" `{s}`"));
1524 tcx.dcx()
1525 .emit_err(diagnostics::SIMDFFIHighlyExperimental { span: hir_ty.span, snip });
1526 }
1527 };
1528 for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
1529 check(input, *ty)
1530 }
1531 if let hir::FnRetTy::Return(ty) = decl.output {
1532 check(ty, fty.output().skip_binder())
1533 }
1534 }
1535
1536 fty
1537}
1538
1539fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
1540 match tcx.hir_node_by_def_id(def_id) {
1541 Node::Expr(&hir::Expr {
1542 kind:
1543 hir::ExprKind::Closure(&rustc_hir::Closure {
1544 kind: hir::ClosureKind::Coroutine(kind),
1545 ..
1546 }),
1547 ..
1548 }) => Some(kind),
1549 _ => None,
1550 }
1551}
1552
1553fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
1554 let &rustc_hir::Closure { kind: hir::ClosureKind::CoroutineClosure(_), body, .. } =
1555 tcx.hir_node_by_def_id(def_id).expect_closure()
1556 else {
1557 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!()
1558 };
1559
1560 let &hir::Expr {
1561 kind:
1562 hir::ExprKind::Closure(&rustc_hir::Closure {
1563 def_id,
1564 kind: hir::ClosureKind::Coroutine(_),
1565 ..
1566 }),
1567 ..
1568 } = tcx.hir_body(body).value
1569 else {
1570 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!()
1571 };
1572
1573 def_id.to_def_id()
1574}
1575
1576fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueTyOrigin<DefId> {
1577 match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
1578 hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl } => {
1579 hir::OpaqueTyOrigin::FnReturn { parent: parent.to_def_id(), in_trait_or_impl }
1580 }
1581 hir::OpaqueTyOrigin::AsyncFn { parent, in_trait_or_impl } => {
1582 hir::OpaqueTyOrigin::AsyncFn { parent: parent.to_def_id(), in_trait_or_impl }
1583 }
1584 hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty } => {
1585 hir::OpaqueTyOrigin::TyAlias { parent: parent.to_def_id(), in_assoc_ty }
1586 }
1587 }
1588}
1589
1590fn rendered_precise_capturing_args<'tcx>(
1591 tcx: TyCtxt<'tcx>,
1592 def_id: LocalDefId,
1593) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
1594 if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
1595 tcx.opt_rpitit_info(def_id.to_def_id())
1596 {
1597 return tcx.rendered_precise_capturing_args(opaque_def_id);
1598 }
1599
1600 tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
1601 hir::GenericBound::Use(args, ..) => {
1602 Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg {
1603 PreciseCapturingArgKind::Lifetime(_) => {
1604 PreciseCapturingArgKind::Lifetime(arg.name())
1605 }
1606 PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()),
1607 })))
1608 }
1609 _ => None,
1610 })
1611}
1612
1613fn const_param_default<'tcx>(
1614 tcx: TyCtxt<'tcx>,
1615 local_def_id: LocalDefId,
1616) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1617 let hir::Node::GenericParam(hir::GenericParam {
1618 kind: hir::GenericParamKind::Const { default: Some(default_ct), .. },
1619 ..
1620 }) = tcx.hir_node_by_def_id(local_def_id)
1621 else {
1622 ::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!(
1623 tcx.def_span(local_def_id),
1624 "`const_param_default` expected a generic parameter with a constant"
1625 )
1626 };
1627
1628 let icx = ItemCtxt::new(tcx, local_def_id);
1629
1630 let def_id = local_def_id.to_def_id();
1631 let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id));
1632
1633 let ct = icx.lowerer().lower_const_arg(
1634 default_ct,
1635 tcx.type_of(def_id).instantiate(tcx, identity_args).skip_norm_wip(),
1636 );
1637 ty::EarlyBinder::bind(tcx, ct)
1638}
1639
1640fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKind {
1641 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);
1642 let hir_id = tcx.local_def_id_to_hir_id(def);
1643 let parent_node_id = tcx.parent_hir_id(hir_id);
1644 match tcx.hir_node(parent_node_id) {
1645 hir::Node::ConstArg(const_arg) => {
1646 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);
1647 if tcx.features().generic_const_exprs() {
1648 ty::AnonConstKind::GCE
1649 } else if tcx.features().min_generic_const_args() {
1650 ty::AnonConstKind::MCG
1651 } else if let hir::Node::Expr(hir::Expr {
1652 kind: hir::ExprKind::Repeat(_, repeat_count),
1653 ..
1654 }) = tcx.parent_hir_node(parent_node_id)
1655 && repeat_count.hir_id == parent_node_id
1656 {
1657 ty::AnonConstKind::RepeatExprCount
1658 } else {
1659 ty::AnonConstKind::MCG
1660 }
1661 }
1662 hir::Node::Expr(hir::Expr {
1663 kind: hir::ExprKind::ConstBlock(..) | hir::ExprKind::InlineAsm(..),
1664 ..
1665 }) => ty::AnonConstKind::NonTypeSystemInline,
1666 _ => ty::AnonConstKind::NonTypeSystemAnon,
1667 }
1668}
1669
1670x;#[instrument(level = "debug", skip(tcx), ret)]
1671fn const_of_item<'tcx>(
1672 tcx: TyCtxt<'tcx>,
1673 def_id: LocalDefId,
1674) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1675 let ct_rhs = match tcx.hir_node_by_def_id(def_id) {
1676 hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => *ct,
1677 hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(_, ct), .. }) => {
1678 ct.expect("no default value for trait assoc const")
1679 }
1680 hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => *ct,
1681 _ => {
1682 span_bug!(tcx.def_span(def_id), "`const_of_item` expected a const or assoc const item")
1683 }
1684 };
1685 let ct_arg = match ct_rhs {
1686 hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg,
1687 hir::ConstItemRhs::Body(_) => {
1688 let e = tcx.dcx().span_delayed_bug(
1689 tcx.def_span(def_id),
1690 "cannot call const_of_item on a non-type_const",
1691 );
1692 return ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e));
1693 }
1694 };
1695 let icx = ItemCtxt::new(tcx, def_id);
1696 let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
1697 let ct = icx.lowerer().lower_const_arg(
1698 ct_arg,
1699 tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args).skip_norm_wip(),
1700 );
1701 if let Err(e) = icx.check_tainted_by_errors()
1702 && !ct.references_error()
1703 {
1704 ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e))
1705 } else {
1706 ty::EarlyBinder::bind(tcx, ct)
1707 }
1708}