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