1mod bounds;
17mod cmse;
18mod dyn_compatibility;
19pub mod errors;
20pub mod generics;
21mod lint;
22
23use std::assert_matches::assert_matches;
24use std::slice;
25
26use rustc_ast::TraitObjectSyntax;
27use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
28use rustc_errors::codes::*;
29use rustc_errors::{
30 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
31};
32use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
33use rustc_hir::def_id::{DefId, LocalDefId};
34use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
35use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
36use rustc_infer::traits::ObligationCause;
37use rustc_middle::middle::stability::AllowUnstable;
38use rustc_middle::mir::interpret::LitToConstInput;
39use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
40use rustc_middle::ty::{
41 self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
42 TypeVisitableExt, TypingMode, Upcast, fold_regions,
43};
44use rustc_middle::{bug, span_bug};
45use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
46use rustc_session::parse::feature_err;
47use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
48use rustc_trait_selection::infer::InferCtxtExt;
49use rustc_trait_selection::traits::wf::object_region_bounds;
50use rustc_trait_selection::traits::{self, ObligationCtxt};
51use tracing::{debug, instrument};
52
53use crate::check::check_abi_fn_ptr;
54use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation};
55use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
56use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
57use crate::middle::resolve_bound_vars as rbv;
58use crate::require_c_abi_if_c_variadic;
59
60#[derive(Debug)]
62pub struct GenericPathSegment(pub DefId, pub usize);
63
64#[derive(Copy, Clone, Debug)]
65pub enum PredicateFilter {
66 All,
68
69 SelfOnly,
71
72 SelfTraitThatDefines(Ident),
76
77 SelfAndAssociatedTypeBounds,
81
82 ConstIfConst,
84
85 SelfConstIfConst,
87}
88
89#[derive(Debug)]
90pub enum RegionInferReason<'a> {
91 ExplicitObjectLifetime,
93 ObjectLifetimeDefault,
95 Param(&'a ty::GenericParamDef),
97 RegionPredicate,
98 Reference,
99 OutlivesBound,
100}
101
102pub trait HirTyLowerer<'tcx> {
107 fn tcx(&self) -> TyCtxt<'tcx>;
108
109 fn dcx(&self) -> DiagCtxtHandle<'_>;
110
111 fn item_def_id(&self) -> LocalDefId;
113
114 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
116
117 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
119
120 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
122
123 fn register_trait_ascription_bounds(
124 &self,
125 bounds: Vec<(ty::Clause<'tcx>, Span)>,
126 hir_id: HirId,
127 span: Span,
128 );
129
130 fn probe_ty_param_bounds(
145 &self,
146 span: Span,
147 def_id: LocalDefId,
148 assoc_ident: Ident,
149 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
150
151 fn lower_assoc_item_path(
164 &self,
165 span: Span,
166 item_def_id: DefId,
167 item_segment: &hir::PathSegment<'tcx>,
168 poly_trait_ref: ty::PolyTraitRef<'tcx>,
169 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
170
171 fn lower_fn_sig(
172 &self,
173 decl: &hir::FnDecl<'tcx>,
174 generics: Option<&hir::Generics<'_>>,
175 hir_id: HirId,
176 hir_ty: Option<&hir::Ty<'_>>,
177 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
178
179 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
186
187 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
189
190 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
192
193 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
198 where
199 Self: Sized,
200 {
201 self
202 }
203}
204
205enum AssocItemQSelf {
209 Trait(DefId),
210 TyParam(LocalDefId, Span),
211 SelfTyAlias,
212}
213
214impl AssocItemQSelf {
215 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
216 match *self {
217 Self::Trait(def_id) => tcx.def_path_str(def_id),
218 Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
219 Self::SelfTyAlias => kw::SelfUpper.to_string(),
220 }
221 }
222}
223
224#[derive(Debug, Clone, Copy)]
231pub enum FeedConstTy<'a, 'tcx> {
232 Param(DefId, &'a [ty::GenericArg<'tcx>]),
240 No,
242}
243
244#[derive(Debug, Clone, Copy)]
245enum LowerTypeRelativePathMode {
246 Type(PermitVariants),
247 Const,
248}
249
250impl LowerTypeRelativePathMode {
251 fn assoc_tag(self) -> ty::AssocTag {
252 match self {
253 Self::Type(_) => ty::AssocTag::Type,
254 Self::Const => ty::AssocTag::Const,
255 }
256 }
257
258 fn def_kind(self) -> DefKind {
259 match self {
260 Self::Type(_) => DefKind::AssocTy,
261 Self::Const => DefKind::AssocConst,
262 }
263 }
264
265 fn permit_variants(self) -> PermitVariants {
266 match self {
267 Self::Type(permit_variants) => permit_variants,
268 Self::Const => PermitVariants::No,
271 }
272 }
273}
274
275#[derive(Debug, Clone, Copy)]
277pub enum PermitVariants {
278 Yes,
279 No,
280}
281
282#[derive(Debug, Clone, Copy)]
283enum TypeRelativePath<'tcx> {
284 AssocItem(DefId, GenericArgsRef<'tcx>),
285 Variant { adt: Ty<'tcx>, variant_did: DefId },
286}
287
288#[derive(Copy, Clone, PartialEq, Debug)]
298pub enum ExplicitLateBound {
299 Yes,
300 No,
301}
302
303#[derive(Copy, Clone, PartialEq)]
304pub enum IsMethodCall {
305 Yes,
306 No,
307}
308
309#[derive(Copy, Clone, PartialEq)]
312pub(crate) enum GenericArgPosition {
313 Type,
314 Value, MethodCall,
316}
317
318#[derive(Clone, Debug)]
321pub struct GenericArgCountMismatch {
322 pub reported: ErrorGuaranteed,
323 pub invalid_args: Vec<usize>,
325}
326
327#[derive(Clone, Debug)]
330pub struct GenericArgCountResult {
331 pub explicit_late_bound: ExplicitLateBound,
332 pub correct: Result<(), GenericArgCountMismatch>,
333}
334
335pub trait GenericArgsLowerer<'a, 'tcx> {
340 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
341
342 fn provided_kind(
343 &mut self,
344 preceding_args: &[ty::GenericArg<'tcx>],
345 param: &ty::GenericParamDef,
346 arg: &GenericArg<'tcx>,
347 ) -> ty::GenericArg<'tcx>;
348
349 fn inferred_kind(
350 &mut self,
351 preceding_args: &[ty::GenericArg<'tcx>],
352 param: &ty::GenericParamDef,
353 infer_args: bool,
354 ) -> ty::GenericArg<'tcx>;
355}
356
357impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
358 #[instrument(level = "debug", skip(self), ret)]
360 pub fn lower_lifetime(
361 &self,
362 lifetime: &hir::Lifetime,
363 reason: RegionInferReason<'_>,
364 ) -> ty::Region<'tcx> {
365 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
366 self.lower_resolved_lifetime(resolved)
367 } else {
368 self.re_infer(lifetime.ident.span, reason)
369 }
370 }
371
372 #[instrument(level = "debug", skip(self), ret)]
374 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
375 let tcx = self.tcx();
376 let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id));
377
378 match resolved {
379 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
380
381 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
382 let name = lifetime_name(def_id);
383 let br = ty::BoundRegion {
384 var: ty::BoundVar::from_u32(index),
385 kind: ty::BoundRegionKind::Named(def_id.to_def_id(), name),
386 };
387 ty::Region::new_bound(tcx, debruijn, br)
388 }
389
390 rbv::ResolvedArg::EarlyBound(def_id) => {
391 let name = tcx.hir_ty_param_name(def_id);
392 let item_def_id = tcx.hir_ty_param_owner(def_id);
393 let generics = tcx.generics_of(item_def_id);
394 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
395 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
396 }
397
398 rbv::ResolvedArg::Free(scope, id) => {
399 let name = lifetime_name(id);
400 ty::Region::new_late_param(
401 tcx,
402 scope.to_def_id(),
403 ty::LateParamRegionKind::Named(id.to_def_id(), name),
404 )
405
406 }
408
409 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
410 }
411 }
412
413 pub fn lower_generic_args_of_path_segment(
414 &self,
415 span: Span,
416 def_id: DefId,
417 item_segment: &hir::PathSegment<'tcx>,
418 ) -> GenericArgsRef<'tcx> {
419 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
420 if let Some(c) = item_segment.args().constraints.first() {
421 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
422 }
423 args
424 }
425
426 #[instrument(level = "debug", skip(self, span), ret)]
461 fn lower_generic_args_of_path(
462 &self,
463 span: Span,
464 def_id: DefId,
465 parent_args: &[ty::GenericArg<'tcx>],
466 segment: &hir::PathSegment<'tcx>,
467 self_ty: Option<Ty<'tcx>>,
468 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
469 let tcx = self.tcx();
474 let generics = tcx.generics_of(def_id);
475 debug!(?generics);
476
477 if generics.has_self {
478 if generics.parent.is_some() {
479 assert!(!parent_args.is_empty())
482 } else {
483 assert!(self_ty.is_some());
485 }
486 } else {
487 assert!(self_ty.is_none());
488 }
489
490 let arg_count = check_generic_arg_count(
491 self,
492 def_id,
493 segment,
494 generics,
495 GenericArgPosition::Type,
496 self_ty.is_some(),
497 );
498
499 if generics.is_own_empty() {
504 return (tcx.mk_args(parent_args), arg_count);
505 }
506
507 struct GenericArgsCtxt<'a, 'tcx> {
508 lowerer: &'a dyn HirTyLowerer<'tcx>,
509 def_id: DefId,
510 generic_args: &'a GenericArgs<'tcx>,
511 span: Span,
512 infer_args: bool,
513 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
514 }
515
516 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
517 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
518 if did == self.def_id {
519 (Some(self.generic_args), self.infer_args)
520 } else {
521 (None, false)
523 }
524 }
525
526 fn provided_kind(
527 &mut self,
528 preceding_args: &[ty::GenericArg<'tcx>],
529 param: &ty::GenericParamDef,
530 arg: &GenericArg<'tcx>,
531 ) -> ty::GenericArg<'tcx> {
532 let tcx = self.lowerer.tcx();
533
534 if let Err(incorrect) = self.incorrect_args {
535 if incorrect.invalid_args.contains(&(param.index as usize)) {
536 return param.to_error(tcx);
537 }
538 }
539
540 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
541 if has_default {
542 tcx.check_optional_stability(
543 param.def_id,
544 Some(arg.hir_id()),
545 arg.span(),
546 None,
547 AllowUnstable::No,
548 |_, _| {
549 },
555 );
556 }
557 self.lowerer.lower_ty(ty).into()
558 };
559
560 match (¶m.kind, arg) {
561 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
562 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
563 }
564 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
565 handle_ty_args(has_default, ty.as_unambig_ty())
567 }
568 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
569 handle_ty_args(has_default, &inf.to_ty())
570 }
571 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
572 .lowerer
573 .lower_const_arg(
575 ct.as_unambig_ct(),
576 FeedConstTy::Param(param.def_id, preceding_args),
577 )
578 .into(),
579 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
580 self.lowerer.ct_infer(Some(param), inf.span).into()
581 }
582 (kind, arg) => span_bug!(
583 self.span,
584 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
585 ),
586 }
587 }
588
589 fn inferred_kind(
590 &mut self,
591 preceding_args: &[ty::GenericArg<'tcx>],
592 param: &ty::GenericParamDef,
593 infer_args: bool,
594 ) -> ty::GenericArg<'tcx> {
595 let tcx = self.lowerer.tcx();
596
597 if let Err(incorrect) = self.incorrect_args {
598 if incorrect.invalid_args.contains(&(param.index as usize)) {
599 return param.to_error(tcx);
600 }
601 }
602 match param.kind {
603 GenericParamDefKind::Lifetime => {
604 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
605 }
606 GenericParamDefKind::Type { has_default, .. } => {
607 if !infer_args && has_default {
608 if let Some(prev) =
610 preceding_args.iter().find_map(|arg| match arg.unpack() {
611 GenericArgKind::Type(ty) => ty.error_reported().err(),
612 _ => None,
613 })
614 {
615 return Ty::new_error(tcx, prev).into();
617 }
618 tcx.at(self.span)
619 .type_of(param.def_id)
620 .instantiate(tcx, preceding_args)
621 .into()
622 } else if infer_args {
623 self.lowerer.ty_infer(Some(param), self.span).into()
624 } else {
625 Ty::new_misc_error(tcx).into()
627 }
628 }
629 GenericParamDefKind::Const { has_default, .. } => {
630 let ty = tcx
631 .at(self.span)
632 .type_of(param.def_id)
633 .instantiate(tcx, preceding_args);
634 if let Err(guar) = ty.error_reported() {
635 return ty::Const::new_error(tcx, guar).into();
636 }
637 if !infer_args && has_default {
638 tcx.const_param_default(param.def_id)
639 .instantiate(tcx, preceding_args)
640 .into()
641 } else if infer_args {
642 self.lowerer.ct_infer(Some(param), self.span).into()
643 } else {
644 ty::Const::new_misc_error(tcx).into()
646 }
647 }
648 }
649 }
650 }
651
652 let mut args_ctx = GenericArgsCtxt {
653 lowerer: self,
654 def_id,
655 span,
656 generic_args: segment.args(),
657 infer_args: segment.infer_args,
658 incorrect_args: &arg_count.correct,
659 };
660 let args = lower_generic_args(
661 self,
662 def_id,
663 parent_args,
664 self_ty.is_some(),
665 self_ty,
666 &arg_count,
667 &mut args_ctx,
668 );
669
670 (args, arg_count)
671 }
672
673 #[instrument(level = "debug", skip(self))]
674 pub fn lower_generic_args_of_assoc_item(
675 &self,
676 span: Span,
677 item_def_id: DefId,
678 item_segment: &hir::PathSegment<'tcx>,
679 parent_args: GenericArgsRef<'tcx>,
680 ) -> GenericArgsRef<'tcx> {
681 let (args, _) =
682 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
683 if let Some(c) = item_segment.args().constraints.first() {
684 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
685 }
686 args
687 }
688
689 pub fn lower_impl_trait_ref(
693 &self,
694 trait_ref: &hir::TraitRef<'tcx>,
695 self_ty: Ty<'tcx>,
696 ) -> ty::TraitRef<'tcx> {
697 let _ = self.prohibit_generic_args(
698 trait_ref.path.segments.split_last().unwrap().1.iter(),
699 GenericsArgsErrExtend::None,
700 );
701
702 self.lower_mono_trait_ref(
703 trait_ref.path.span,
704 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
705 self_ty,
706 trait_ref.path.segments.last().unwrap(),
707 true,
708 )
709 }
710
711 #[instrument(level = "debug", skip(self, span, constness, bounds))]
735 pub(crate) fn lower_poly_trait_ref(
736 &self,
737 trait_ref: &hir::TraitRef<'tcx>,
738 span: Span,
739 constness: hir::BoundConstness,
740 polarity: hir::BoundPolarity,
741 self_ty: Ty<'tcx>,
742 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
743 predicate_filter: PredicateFilter,
744 ) -> GenericArgCountResult {
745 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
746 let trait_segment = trait_ref.path.segments.last().unwrap();
747
748 let _ = self.prohibit_generic_args(
749 trait_ref.path.segments.split_last().unwrap().1.iter(),
750 GenericsArgsErrExtend::None,
751 );
752 self.report_internal_fn_trait(span, trait_def_id, trait_segment, false);
753
754 let (generic_args, arg_count) = self.lower_generic_args_of_path(
755 trait_ref.path.span,
756 trait_def_id,
757 &[],
758 trait_segment,
759 Some(self_ty),
760 );
761
762 let tcx = self.tcx();
763 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
764 debug!(?bound_vars);
765
766 let poly_trait_ref = ty::Binder::bind_with_vars(
767 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
768 bound_vars,
769 );
770
771 debug!(?poly_trait_ref);
772
773 let polarity = match polarity {
774 rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
775 rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
776 rustc_ast::BoundPolarity::Maybe(_) => {
777 for constraint in trait_segment.args().constraints {
780 let _ = self.lower_assoc_item_constraint(
781 trait_ref.hir_ref_id,
782 poly_trait_ref,
783 constraint,
784 &mut Default::default(),
785 &mut Default::default(),
786 constraint.span,
787 predicate_filter,
788 );
789 }
790 return arg_count;
791 }
792 };
793
794 match predicate_filter {
796 PredicateFilter::All
797 | PredicateFilter::SelfOnly
798 | PredicateFilter::SelfTraitThatDefines(..)
799 | PredicateFilter::SelfAndAssociatedTypeBounds => {
800 let bound = poly_trait_ref.map_bound(|trait_ref| {
801 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
802 });
803 let bound = (bound.upcast(tcx), span);
804 if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
806 bounds.insert(0, bound);
807 } else {
808 bounds.push(bound);
809 }
810 }
811 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
812 }
813
814 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
815 && !self.tcx().is_const_trait(trait_def_id)
816 {
817 let (def_span, suggestion, suggestion_pre) =
818 match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) {
819 (true, true) => (
820 None,
821 Some(tcx.def_span(trait_def_id).shrink_to_lo()),
822 if self.tcx().features().const_trait_impl() {
823 ""
824 } else {
825 "enable `#![feature(const_trait_impl)]` in your crate and "
826 },
827 ),
828 (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
829 };
830 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
831 span,
832 modifier: constness.as_str(),
833 def_span,
834 trait_name: self.tcx().def_path_str(trait_def_id),
835 suggestion_pre,
836 suggestion,
837 });
838 } else {
839 match predicate_filter {
840 PredicateFilter::SelfTraitThatDefines(..) => {}
842 PredicateFilter::All
843 | PredicateFilter::SelfOnly
844 | PredicateFilter::SelfAndAssociatedTypeBounds => {
845 match constness {
846 hir::BoundConstness::Always(_) => {
847 if polarity == ty::PredicatePolarity::Positive {
848 bounds.push((
849 poly_trait_ref
850 .to_host_effect_clause(tcx, ty::BoundConstness::Const),
851 span,
852 ));
853 }
854 }
855 hir::BoundConstness::Maybe(_) => {
856 }
861 hir::BoundConstness::Never => {}
862 }
863 }
864 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
871 match constness {
872 hir::BoundConstness::Maybe(_) => {
873 if polarity == ty::PredicatePolarity::Positive {
874 bounds.push((
875 poly_trait_ref
876 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
877 span,
878 ));
879 }
880 }
881 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
882 }
883 }
884 }
885 }
886
887 let mut dup_constraints = FxIndexMap::default();
888 for constraint in trait_segment.args().constraints {
889 if polarity != ty::PredicatePolarity::Positive {
893 self.dcx().span_delayed_bug(
894 constraint.span,
895 "negative trait bounds should not have assoc item constraints",
896 );
897 break;
898 }
899
900 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
902 trait_ref.hir_ref_id,
903 poly_trait_ref,
904 constraint,
905 bounds,
906 &mut dup_constraints,
907 constraint.span,
908 predicate_filter,
909 );
910 }
912
913 arg_count
914 }
915
916 fn lower_mono_trait_ref(
920 &self,
921 span: Span,
922 trait_def_id: DefId,
923 self_ty: Ty<'tcx>,
924 trait_segment: &hir::PathSegment<'tcx>,
925 is_impl: bool,
926 ) -> ty::TraitRef<'tcx> {
927 self.report_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
928
929 let (generic_args, _) =
930 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
931 if let Some(c) = trait_segment.args().constraints.first() {
932 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
933 }
934 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
935 }
936
937 fn probe_trait_that_defines_assoc_item(
938 &self,
939 trait_def_id: DefId,
940 assoc_tag: ty::AssocTag,
941 assoc_ident: Ident,
942 ) -> bool {
943 self.tcx()
944 .associated_items(trait_def_id)
945 .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
946 .is_some()
947 }
948
949 fn lower_path_segment(
950 &self,
951 span: Span,
952 did: DefId,
953 item_segment: &hir::PathSegment<'tcx>,
954 ) -> Ty<'tcx> {
955 let tcx = self.tcx();
956 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
957
958 if let DefKind::TyAlias = tcx.def_kind(did)
959 && tcx.type_alias_is_lazy(did)
960 {
961 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
965 Ty::new_alias(tcx, ty::Free, alias_ty)
966 } else {
967 tcx.at(span).type_of(did).instantiate(tcx, args)
968 }
969 }
970
971 #[instrument(level = "debug", skip_all, ret)]
979 fn probe_single_ty_param_bound_for_assoc_item(
980 &self,
981 ty_param_def_id: LocalDefId,
982 ty_param_span: Span,
983 assoc_tag: ty::AssocTag,
984 assoc_ident: Ident,
985 span: Span,
986 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
987 debug!(?ty_param_def_id, ?assoc_ident, ?span);
988 let tcx = self.tcx();
989
990 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
991 debug!("predicates={:#?}", predicates);
992
993 self.probe_single_bound_for_assoc_item(
994 || {
995 let trait_refs = predicates
996 .iter_identity_copied()
997 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
998 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
999 },
1000 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
1001 assoc_tag,
1002 assoc_ident,
1003 span,
1004 None,
1005 )
1006 }
1007
1008 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1014 fn probe_single_bound_for_assoc_item<I>(
1015 &self,
1016 all_candidates: impl Fn() -> I,
1017 qself: AssocItemQSelf,
1018 assoc_tag: ty::AssocTag,
1019 assoc_ident: Ident,
1020 span: Span,
1021 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1022 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1023 where
1024 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1025 {
1026 let tcx = self.tcx();
1027
1028 let mut matching_candidates = all_candidates().filter(|r| {
1029 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
1030 });
1031
1032 let Some(bound) = matching_candidates.next() else {
1033 return Err(self.report_unresolved_assoc_item(
1034 all_candidates,
1035 qself,
1036 assoc_tag,
1037 assoc_ident,
1038 span,
1039 constraint,
1040 ));
1041 };
1042 debug!(?bound);
1043
1044 if let Some(bound2) = matching_candidates.next() {
1045 debug!(?bound2);
1046
1047 let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
1048 let qself_str = qself.to_string(tcx);
1049 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1050 span,
1051 assoc_kind: assoc_kind_str,
1052 assoc_ident,
1053 qself: &qself_str,
1054 });
1055 err.code(
1057 if let Some(constraint) = constraint
1058 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1059 {
1060 E0222
1061 } else {
1062 E0221
1063 },
1064 );
1065
1066 let mut where_bounds = vec![];
1070 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1071 let bound_id = bound.def_id();
1072 let bound_span = tcx
1073 .associated_items(bound_id)
1074 .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1075 .and_then(|item| tcx.hir_span_if_local(item.def_id));
1076
1077 if let Some(bound_span) = bound_span {
1078 err.span_label(
1079 bound_span,
1080 format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
1081 );
1082 if let Some(constraint) = constraint {
1083 match constraint.kind {
1084 hir::AssocItemConstraintKind::Equality { term } => {
1085 let term: ty::Term<'_> = match term {
1086 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1087 hir::Term::Const(ct) => {
1088 self.lower_const_arg(ct, FeedConstTy::No).into()
1089 }
1090 };
1091 if term.references_error() {
1092 continue;
1093 }
1094 where_bounds.push(format!(
1096 " T: {trait}::{assoc_ident} = {term}",
1097 trait = bound.print_only_trait_path(),
1098 ));
1099 }
1100 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1102 }
1103 } else {
1104 err.span_suggestion_verbose(
1105 span.with_hi(assoc_ident.span.lo()),
1106 "use fully-qualified syntax to disambiguate",
1107 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1108 Applicability::MaybeIncorrect,
1109 );
1110 }
1111 } else {
1112 err.note(format!(
1113 "associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`",
1114 bound.print_only_trait_path(),
1115 ));
1116 }
1117 }
1118 if !where_bounds.is_empty() {
1119 err.help(format!(
1120 "consider introducing a new type parameter `T` and adding `where` constraints:\
1121 \n where\n T: {qself_str},\n{}",
1122 where_bounds.join(",\n"),
1123 ));
1124 let reported = err.emit();
1125 return Err(reported);
1126 }
1127 err.emit();
1128 }
1129
1130 Ok(bound)
1131 }
1132
1133 #[instrument(level = "debug", skip_all, ret)]
1160 pub fn lower_type_relative_ty_path(
1161 &self,
1162 self_ty: Ty<'tcx>,
1163 hir_self_ty: &'tcx hir::Ty<'tcx>,
1164 segment: &'tcx hir::PathSegment<'tcx>,
1165 qpath_hir_id: HirId,
1166 span: Span,
1167 permit_variants: PermitVariants,
1168 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1169 let tcx = self.tcx();
1170 match self.lower_type_relative_path(
1171 self_ty,
1172 hir_self_ty,
1173 segment,
1174 qpath_hir_id,
1175 span,
1176 LowerTypeRelativePathMode::Type(permit_variants),
1177 )? {
1178 TypeRelativePath::AssocItem(def_id, args) => {
1179 let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1180 let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1181 Ok((ty, tcx.def_kind(def_id), def_id))
1182 }
1183 TypeRelativePath::Variant { adt, variant_did } => {
1184 Ok((adt, DefKind::Variant, variant_did))
1185 }
1186 }
1187 }
1188
1189 #[instrument(level = "debug", skip_all, ret)]
1191 fn lower_type_relative_const_path(
1192 &self,
1193 self_ty: Ty<'tcx>,
1194 hir_self_ty: &'tcx hir::Ty<'tcx>,
1195 segment: &'tcx hir::PathSegment<'tcx>,
1196 qpath_hir_id: HirId,
1197 span: Span,
1198 ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1199 let tcx = self.tcx();
1200 let (def_id, args) = match self.lower_type_relative_path(
1201 self_ty,
1202 hir_self_ty,
1203 segment,
1204 qpath_hir_id,
1205 span,
1206 LowerTypeRelativePathMode::Const,
1207 )? {
1208 TypeRelativePath::AssocItem(def_id, args) => {
1209 if !tcx.associated_item(def_id).is_type_const_capable(tcx) {
1210 let mut err = self.dcx().struct_span_err(
1211 span,
1212 "use of trait associated const without `#[type_const]`",
1213 );
1214 err.note("the declaration in the trait must be marked with `#[type_const]`");
1215 return Err(err.emit());
1216 }
1217 (def_id, args)
1218 }
1219 TypeRelativePath::Variant { .. } => {
1222 span_bug!(span, "unexpected variant res for type associated const path")
1223 }
1224 };
1225 Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
1226 }
1227
1228 #[instrument(level = "debug", skip_all, ret)]
1230 fn lower_type_relative_path(
1231 &self,
1232 self_ty: Ty<'tcx>,
1233 hir_self_ty: &'tcx hir::Ty<'tcx>,
1234 segment: &'tcx hir::PathSegment<'tcx>,
1235 qpath_hir_id: HirId,
1236 span: Span,
1237 mode: LowerTypeRelativePathMode,
1238 ) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
1239 debug!(%self_ty, ?segment.ident);
1240 let tcx = self.tcx();
1241
1242 let mut variant_def_id = None;
1244 if let Some(adt_def) = self.probe_adt(span, self_ty) {
1245 if adt_def.is_enum() {
1246 let variant_def = adt_def
1247 .variants()
1248 .iter()
1249 .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
1250 if let Some(variant_def) = variant_def {
1251 if let PermitVariants::Yes = mode.permit_variants() {
1252 tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1253 let _ = self.prohibit_generic_args(
1254 slice::from_ref(segment).iter(),
1255 GenericsArgsErrExtend::EnumVariant {
1256 qself: hir_self_ty,
1257 assoc_segment: segment,
1258 adt_def,
1259 },
1260 );
1261 return Ok(TypeRelativePath::Variant {
1262 adt: self_ty,
1263 variant_did: variant_def.def_id,
1264 });
1265 } else {
1266 variant_def_id = Some(variant_def.def_id);
1267 }
1268 }
1269 }
1270
1271 if let Some((did, args)) = self.probe_inherent_assoc_item(
1273 segment,
1274 adt_def.did(),
1275 self_ty,
1276 qpath_hir_id,
1277 span,
1278 mode.assoc_tag(),
1279 )? {
1280 return Ok(TypeRelativePath::AssocItem(did, args));
1281 }
1282 }
1283
1284 let (item_def_id, bound) = self.resolve_type_relative_path(
1285 self_ty,
1286 hir_self_ty,
1287 mode.assoc_tag(),
1288 segment,
1289 qpath_hir_id,
1290 span,
1291 variant_def_id,
1292 )?;
1293
1294 let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
1295
1296 if let Some(variant_def_id) = variant_def_id {
1297 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
1298 lint.primary_message("ambiguous associated item");
1299 let mut could_refer_to = |kind: DefKind, def_id, also| {
1300 let note_msg = format!(
1301 "`{}` could{} refer to the {} defined here",
1302 segment.ident,
1303 also,
1304 tcx.def_kind_descr(kind, def_id)
1305 );
1306 lint.span_note(tcx.def_span(def_id), note_msg);
1307 };
1308
1309 could_refer_to(DefKind::Variant, variant_def_id, "");
1310 could_refer_to(mode.def_kind(), item_def_id, " also");
1311
1312 lint.span_suggestion(
1313 span,
1314 "use fully-qualified syntax",
1315 format!(
1316 "<{} as {}>::{}",
1317 self_ty,
1318 tcx.item_name(bound.def_id()),
1319 segment.ident
1320 ),
1321 Applicability::MachineApplicable,
1322 );
1323 });
1324 }
1325
1326 Ok(TypeRelativePath::AssocItem(item_def_id, args))
1327 }
1328
1329 fn resolve_type_relative_path(
1331 &self,
1332 self_ty: Ty<'tcx>,
1333 hir_self_ty: &'tcx hir::Ty<'tcx>,
1334 assoc_tag: ty::AssocTag,
1335 segment: &'tcx hir::PathSegment<'tcx>,
1336 qpath_hir_id: HirId,
1337 span: Span,
1338 variant_def_id: Option<DefId>,
1339 ) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
1340 let tcx = self.tcx();
1341
1342 let self_ty_res = match hir_self_ty.kind {
1343 hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
1344 _ => Res::Err,
1345 };
1346
1347 let bound = match (self_ty.kind(), self_ty_res) {
1349 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1350 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1353 self.dcx().span_bug(span, "expected cycle error");
1355 };
1356
1357 self.probe_single_bound_for_assoc_item(
1358 || {
1359 let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
1360 traits::supertraits(tcx, trait_ref)
1361 },
1362 AssocItemQSelf::SelfTyAlias,
1363 assoc_tag,
1364 segment.ident,
1365 span,
1366 None,
1367 )?
1368 }
1369 (
1370 &ty::Param(_),
1371 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1372 ) => self.probe_single_ty_param_bound_for_assoc_item(
1373 param_did.expect_local(),
1374 hir_self_ty.span,
1375 assoc_tag,
1376 segment.ident,
1377 span,
1378 )?,
1379 _ => {
1380 return Err(self.report_unresolved_type_relative_path(
1381 self_ty,
1382 hir_self_ty,
1383 assoc_tag,
1384 segment.ident,
1385 qpath_hir_id,
1386 span,
1387 variant_def_id,
1388 ));
1389 }
1390 };
1391
1392 let assoc_item = self
1393 .probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
1394 .expect("failed to find associated item");
1395
1396 Ok((assoc_item.def_id, bound))
1397 }
1398
1399 fn probe_inherent_assoc_item(
1401 &self,
1402 segment: &hir::PathSegment<'tcx>,
1403 adt_did: DefId,
1404 self_ty: Ty<'tcx>,
1405 block: HirId,
1406 span: Span,
1407 assoc_tag: ty::AssocTag,
1408 ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1409 let tcx = self.tcx();
1410
1411 if !tcx.features().inherent_associated_types() {
1412 match assoc_tag {
1413 ty::AssocTag::Type => return Ok(None),
1421 ty::AssocTag::Const => {
1422 return Err(feature_err(
1426 &tcx.sess,
1427 sym::inherent_associated_types,
1428 span,
1429 "inherent associated types are unstable",
1430 )
1431 .emit());
1432 }
1433 ty::AssocTag::Fn => unreachable!(),
1434 }
1435 }
1436
1437 let name = segment.ident;
1438 let candidates: Vec<_> = tcx
1439 .inherent_impls(adt_did)
1440 .iter()
1441 .filter_map(|&impl_| {
1442 let (item, scope) =
1443 self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1444 Some((impl_, (item.def_id, scope)))
1445 })
1446 .collect();
1447
1448 if candidates.is_empty() {
1449 return Ok(None);
1450 }
1451
1452 let infcx = match self.infcx() {
1459 Some(infcx) => infcx,
1460 None => {
1461 assert!(!self_ty.has_infer());
1462 &tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis())
1463 }
1464 };
1465
1466 let param_env = tcx.param_env(block.owner);
1469
1470 let mut universes = if self_ty.has_escaping_bound_vars() {
1471 vec![None; self_ty.outer_exclusive_binder().as_usize()]
1472 } else {
1473 vec![]
1474 };
1475
1476 let (impl_, (assoc_item, def_scope)) = crate::traits::with_replaced_escaping_bound_vars(
1477 infcx,
1478 &mut universes,
1479 self_ty,
1480 |self_ty| {
1481 self.select_inherent_assoc_candidates(
1482 infcx, name, span, self_ty, param_env, candidates, assoc_tag,
1483 )
1484 },
1485 )?;
1486
1487 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1488
1489 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1493 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1494 let args = tcx.mk_args_from_iter(
1495 std::iter::once(ty::GenericArg::from(self_ty))
1496 .chain(args.into_iter().skip(parent_args.len())),
1497 );
1498
1499 Ok(Some((assoc_item, args)))
1500 }
1501
1502 fn select_inherent_assoc_candidates(
1503 &self,
1504 infcx: &InferCtxt<'tcx>,
1505 name: Ident,
1506 span: Span,
1507 self_ty: Ty<'tcx>,
1508 param_env: ParamEnv<'tcx>,
1509 candidates: Vec<(DefId, (DefId, DefId))>,
1510 assoc_tag: ty::AssocTag,
1511 ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
1512 let tcx = self.tcx();
1513 let mut fulfillment_errors = Vec::new();
1514
1515 let applicable_candidates: Vec<_> = candidates
1516 .iter()
1517 .copied()
1518 .filter(|&(impl_, _)| {
1519 infcx.probe(|_| {
1520 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
1521 let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
1522
1523 let impl_args = infcx.fresh_args_for_item(span, impl_);
1524 let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1525 let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
1526
1527 if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
1529 return false;
1530 }
1531
1532 let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1534 let impl_bounds =
1535 ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
1536 let impl_obligations = traits::predicates_for_generics(
1537 |_, _| ObligationCause::dummy(),
1538 param_env,
1539 impl_bounds,
1540 );
1541 ocx.register_obligations(impl_obligations);
1542
1543 let mut errors = ocx.select_where_possible();
1544 if !errors.is_empty() {
1545 fulfillment_errors.append(&mut errors);
1546 return false;
1547 }
1548
1549 true
1550 })
1551 })
1552 .collect();
1553
1554 match &applicable_candidates[..] {
1555 &[] => Err(self.report_unresolved_inherent_assoc_item(
1556 name,
1557 self_ty,
1558 candidates,
1559 fulfillment_errors,
1560 span,
1561 assoc_tag,
1562 )),
1563
1564 &[applicable_candidate] => Ok(applicable_candidate),
1565
1566 &[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
1567 name,
1568 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1569 span,
1570 )),
1571 }
1572 }
1573
1574 fn probe_assoc_item(
1578 &self,
1579 ident: Ident,
1580 assoc_tag: ty::AssocTag,
1581 block: HirId,
1582 span: Span,
1583 scope: DefId,
1584 ) -> Option<ty::AssocItem> {
1585 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1586 self.check_assoc_item(item.def_id, ident, scope, block, span);
1587 Some(item)
1588 }
1589
1590 fn probe_assoc_item_unchecked(
1595 &self,
1596 ident: Ident,
1597 assoc_tag: ty::AssocTag,
1598 block: HirId,
1599 scope: DefId,
1600 ) -> Option<(ty::AssocItem, DefId)> {
1601 let tcx = self.tcx();
1602
1603 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1604 let item = tcx
1608 .associated_items(scope)
1609 .filter_by_name_unhygienic(ident.name)
1610 .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1611
1612 Some((*item, def_scope))
1613 }
1614
1615 fn check_assoc_item(
1617 &self,
1618 item_def_id: DefId,
1619 ident: Ident,
1620 scope: DefId,
1621 block: HirId,
1622 span: Span,
1623 ) {
1624 let tcx = self.tcx();
1625
1626 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1627 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1628 span,
1629 kind: tcx.def_descr(item_def_id),
1630 name: ident,
1631 defined_here_label: tcx.def_span(item_def_id),
1632 });
1633 }
1634
1635 tcx.check_stability(item_def_id, Some(block), span, None);
1636 }
1637
1638 fn probe_traits_that_match_assoc_ty(
1639 &self,
1640 qself_ty: Ty<'tcx>,
1641 assoc_ident: Ident,
1642 ) -> Vec<String> {
1643 let tcx = self.tcx();
1644
1645 let infcx_;
1648 let infcx = if let Some(infcx) = self.infcx() {
1649 infcx
1650 } else {
1651 assert!(!qself_ty.has_infer());
1652 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1653 &infcx_
1654 };
1655
1656 tcx.all_traits()
1657 .filter(|trait_def_id| {
1658 tcx.associated_items(*trait_def_id)
1660 .in_definition_order()
1661 .any(|i| {
1662 i.is_type()
1663 && !i.is_impl_trait_in_trait()
1664 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1665 })
1666 && tcx.visibility(*trait_def_id)
1668 .is_accessible_from(self.item_def_id(), tcx)
1669 && tcx.all_impls(*trait_def_id)
1670 .any(|impl_def_id| {
1671 let header = tcx.impl_trait_header(impl_def_id).unwrap();
1672 let trait_ref = header.trait_ref.instantiate(
1673 tcx,
1674 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1675 );
1676
1677 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1678 if value.has_escaping_bound_vars() {
1680 return false;
1681 }
1682 infcx
1683 .can_eq(
1684 ty::ParamEnv::empty(),
1685 trait_ref.self_ty(),
1686 value,
1687 ) && header.polarity != ty::ImplPolarity::Negative
1688 })
1689 })
1690 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1691 .collect()
1692 }
1693
1694 #[instrument(level = "debug", skip_all)]
1696 fn lower_resolved_assoc_ty_path(
1697 &self,
1698 span: Span,
1699 opt_self_ty: Option<Ty<'tcx>>,
1700 item_def_id: DefId,
1701 trait_segment: Option<&hir::PathSegment<'tcx>>,
1702 item_segment: &hir::PathSegment<'tcx>,
1703 ) -> Ty<'tcx> {
1704 match self.lower_resolved_assoc_item_path(
1705 span,
1706 opt_self_ty,
1707 item_def_id,
1708 trait_segment,
1709 item_segment,
1710 ty::AssocTag::Type,
1711 ) {
1712 Ok((item_def_id, item_args)) => {
1713 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1714 }
1715 Err(guar) => Ty::new_error(self.tcx(), guar),
1716 }
1717 }
1718
1719 #[instrument(level = "debug", skip_all)]
1721 fn lower_resolved_assoc_const_path(
1722 &self,
1723 span: Span,
1724 opt_self_ty: Option<Ty<'tcx>>,
1725 item_def_id: DefId,
1726 trait_segment: Option<&hir::PathSegment<'tcx>>,
1727 item_segment: &hir::PathSegment<'tcx>,
1728 ) -> Const<'tcx> {
1729 match self.lower_resolved_assoc_item_path(
1730 span,
1731 opt_self_ty,
1732 item_def_id,
1733 trait_segment,
1734 item_segment,
1735 ty::AssocTag::Const,
1736 ) {
1737 Ok((item_def_id, item_args)) => {
1738 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1739 Const::new_unevaluated(self.tcx(), uv)
1740 }
1741 Err(guar) => Const::new_error(self.tcx(), guar),
1742 }
1743 }
1744
1745 #[instrument(level = "debug", skip_all)]
1747 fn lower_resolved_assoc_item_path(
1748 &self,
1749 span: Span,
1750 opt_self_ty: Option<Ty<'tcx>>,
1751 item_def_id: DefId,
1752 trait_segment: Option<&hir::PathSegment<'tcx>>,
1753 item_segment: &hir::PathSegment<'tcx>,
1754 assoc_tag: ty::AssocTag,
1755 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1756 let tcx = self.tcx();
1757
1758 let trait_def_id = tcx.parent(item_def_id);
1759 debug!(?trait_def_id);
1760
1761 let Some(self_ty) = opt_self_ty else {
1762 return Err(self.report_missing_self_ty_for_resolved_path(
1763 trait_def_id,
1764 span,
1765 item_segment,
1766 assoc_tag,
1767 ));
1768 };
1769 debug!(?self_ty);
1770
1771 let trait_ref =
1772 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
1773 debug!(?trait_ref);
1774
1775 let item_args =
1776 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1777
1778 Ok((item_def_id, item_args))
1779 }
1780
1781 pub fn prohibit_generic_args<'a>(
1782 &self,
1783 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1784 err_extend: GenericsArgsErrExtend<'a>,
1785 ) -> Result<(), ErrorGuaranteed> {
1786 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1787 let mut result = Ok(());
1788 if let Some(_) = args_visitors.clone().next() {
1789 result = Err(self.report_prohibited_generic_args(
1790 segments.clone(),
1791 args_visitors,
1792 err_extend,
1793 ));
1794 }
1795
1796 for segment in segments {
1797 if let Some(c) = segment.args().constraints.first() {
1799 return Err(prohibit_assoc_item_constraint(self, c, None));
1800 }
1801 }
1802
1803 result
1804 }
1805
1806 pub fn probe_generic_path_segments(
1824 &self,
1825 segments: &[hir::PathSegment<'_>],
1826 self_ty: Option<Ty<'tcx>>,
1827 kind: DefKind,
1828 def_id: DefId,
1829 span: Span,
1830 ) -> Vec<GenericPathSegment> {
1831 let tcx = self.tcx();
1877
1878 assert!(!segments.is_empty());
1879 let last = segments.len() - 1;
1880
1881 let mut generic_segments = vec![];
1882
1883 match kind {
1884 DefKind::Ctor(CtorOf::Struct, ..) => {
1886 let generics = tcx.generics_of(def_id);
1889 let generics_def_id = generics.parent.unwrap_or(def_id);
1892 generic_segments.push(GenericPathSegment(generics_def_id, last));
1893 }
1894
1895 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
1897 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
1898 let adt_def = self.probe_adt(span, self_ty).unwrap();
1899 debug_assert!(adt_def.is_enum());
1900 (adt_def.did(), last)
1901 } else if last >= 1 && segments[last - 1].args.is_some() {
1902 let mut def_id = def_id;
1905
1906 if let DefKind::Ctor(..) = kind {
1908 def_id = tcx.parent(def_id);
1909 }
1910
1911 let enum_def_id = tcx.parent(def_id);
1913 (enum_def_id, last - 1)
1914 } else {
1915 let generics = tcx.generics_of(def_id);
1921 (generics.parent.unwrap_or(def_id), last)
1924 };
1925 generic_segments.push(GenericPathSegment(generics_def_id, index));
1926 }
1927
1928 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
1930 generic_segments.push(GenericPathSegment(def_id, last));
1931 }
1932
1933 DefKind::AssocFn | DefKind::AssocConst => {
1935 if segments.len() >= 2 {
1936 let generics = tcx.generics_of(def_id);
1937 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
1938 }
1939 generic_segments.push(GenericPathSegment(def_id, last));
1940 }
1941
1942 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
1943 }
1944
1945 debug!(?generic_segments);
1946
1947 generic_segments
1948 }
1949
1950 #[instrument(level = "debug", skip_all)]
1952 pub fn lower_resolved_ty_path(
1953 &self,
1954 opt_self_ty: Option<Ty<'tcx>>,
1955 path: &hir::Path<'tcx>,
1956 hir_id: HirId,
1957 permit_variants: PermitVariants,
1958 ) -> Ty<'tcx> {
1959 debug!(?path.res, ?opt_self_ty, ?path.segments);
1960 let tcx = self.tcx();
1961
1962 let span = path.span;
1963 match path.res {
1964 Res::Def(DefKind::OpaqueTy, did) => {
1965 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
1967 let item_segment = path.segments.split_last().unwrap();
1968 let _ = self
1969 .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy);
1970 let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0);
1971 Ty::new_opaque(tcx, did, args)
1972 }
1973 Res::Def(
1974 DefKind::Enum
1975 | DefKind::TyAlias
1976 | DefKind::Struct
1977 | DefKind::Union
1978 | DefKind::ForeignTy,
1979 did,
1980 ) => {
1981 assert_eq!(opt_self_ty, None);
1982 let _ = self.prohibit_generic_args(
1983 path.segments.split_last().unwrap().1.iter(),
1984 GenericsArgsErrExtend::None,
1985 );
1986 self.lower_path_segment(span, did, path.segments.last().unwrap())
1987 }
1988 Res::Def(kind @ DefKind::Variant, def_id)
1989 if let PermitVariants::Yes = permit_variants =>
1990 {
1991 assert_eq!(opt_self_ty, None);
1994
1995 let generic_segments =
1996 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
1997 let indices: FxHashSet<_> =
1998 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
1999 let _ = self.prohibit_generic_args(
2000 path.segments.iter().enumerate().filter_map(|(index, seg)| {
2001 if !indices.contains(&index) { Some(seg) } else { None }
2002 }),
2003 GenericsArgsErrExtend::DefVariant(&path.segments),
2004 );
2005
2006 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
2007 self.lower_path_segment(span, *def_id, &path.segments[*index])
2008 }
2009 Res::Def(DefKind::TyParam, def_id) => {
2010 assert_eq!(opt_self_ty, None);
2011 let _ = self.prohibit_generic_args(
2012 path.segments.iter(),
2013 GenericsArgsErrExtend::Param(def_id),
2014 );
2015 self.lower_ty_param(hir_id)
2016 }
2017 Res::SelfTyParam { .. } => {
2018 assert_eq!(opt_self_ty, None);
2020 let _ = self.prohibit_generic_args(
2021 path.segments.iter(),
2022 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2023 GenericsArgsErrExtend::SelfTyParam(
2024 ident.span.shrink_to_hi().to(args.span_ext),
2025 )
2026 } else {
2027 GenericsArgsErrExtend::None
2028 },
2029 );
2030 tcx.types.self_param
2031 }
2032 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
2033 assert_eq!(opt_self_ty, None);
2035 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
2037 let _ = self.prohibit_generic_args(
2038 path.segments.iter(),
2039 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
2040 );
2041 if forbid_generic && ty.has_param() {
2061 let mut err = self.dcx().struct_span_err(
2062 path.span,
2063 "generic `Self` types are currently not permitted in anonymous constants",
2064 );
2065 if let Some(hir::Node::Item(&hir::Item {
2066 kind: hir::ItemKind::Impl(impl_),
2067 ..
2068 })) = tcx.hir_get_if_local(def_id)
2069 {
2070 err.span_note(impl_.self_ty.span, "not a concrete type");
2071 }
2072 let reported = err.emit();
2073 Ty::new_error(tcx, reported)
2074 } else {
2075 ty
2076 }
2077 }
2078 Res::Def(DefKind::AssocTy, def_id) => {
2079 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2080 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2081 Some(trait_)
2082 } else {
2083 None
2084 };
2085 self.lower_resolved_assoc_ty_path(
2086 span,
2087 opt_self_ty,
2088 def_id,
2089 trait_segment,
2090 path.segments.last().unwrap(),
2091 )
2092 }
2093 Res::PrimTy(prim_ty) => {
2094 assert_eq!(opt_self_ty, None);
2095 let _ = self.prohibit_generic_args(
2096 path.segments.iter(),
2097 GenericsArgsErrExtend::PrimTy(prim_ty),
2098 );
2099 match prim_ty {
2100 hir::PrimTy::Bool => tcx.types.bool,
2101 hir::PrimTy::Char => tcx.types.char,
2102 hir::PrimTy::Int(it) => Ty::new_int(tcx, ty::int_ty(it)),
2103 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, ty::uint_ty(uit)),
2104 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ty::float_ty(ft)),
2105 hir::PrimTy::Str => tcx.types.str_,
2106 }
2107 }
2108 Res::Err => {
2109 let e = self
2110 .tcx()
2111 .dcx()
2112 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2113 Ty::new_error(tcx, e)
2114 }
2115 Res::Def(..) => {
2116 assert_eq!(
2117 path.segments.get(0).map(|seg| seg.ident.name),
2118 Some(kw::SelfUpper),
2119 "only expected incorrect resolution for `Self`"
2120 );
2121 Ty::new_error(
2122 self.tcx(),
2123 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2124 )
2125 }
2126 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2127 }
2128 }
2129
2130 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2135 let tcx = self.tcx();
2136 match tcx.named_bound_var(hir_id) {
2137 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2138 let name = tcx.item_name(def_id.to_def_id());
2139 let br = ty::BoundTy {
2140 var: ty::BoundVar::from_u32(index),
2141 kind: ty::BoundTyKind::Param(def_id.to_def_id(), name),
2142 };
2143 Ty::new_bound(tcx, debruijn, br)
2144 }
2145 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2146 let item_def_id = tcx.hir_ty_param_owner(def_id);
2147 let generics = tcx.generics_of(item_def_id);
2148 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2149 Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2150 }
2151 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2152 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2153 }
2154 }
2155
2156 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2161 let tcx = self.tcx();
2162
2163 match tcx.named_bound_var(path_hir_id) {
2164 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2165 let item_def_id = tcx.parent(param_def_id);
2168 let generics = tcx.generics_of(item_def_id);
2169 let index = generics.param_def_id_to_index[¶m_def_id];
2170 let name = tcx.item_name(param_def_id);
2171 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2172 }
2173 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2174 ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
2175 }
2176 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2177 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2178 }
2179 }
2180
2181 #[instrument(skip(self), level = "debug")]
2183 pub fn lower_const_arg(
2184 &self,
2185 const_arg: &hir::ConstArg<'tcx>,
2186 feed: FeedConstTy<'_, 'tcx>,
2187 ) -> Const<'tcx> {
2188 let tcx = self.tcx();
2189
2190 if let FeedConstTy::Param(param_def_id, args) = feed
2191 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2192 {
2193 let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2194
2195 if tcx.features().generic_const_parameter_types()
2204 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2205 {
2206 let e = self.dcx().span_err(
2207 const_arg.span(),
2208 "anonymous constants with lifetimes in their type are not yet supported",
2209 );
2210 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2211 return ty::Const::new_error(tcx, e);
2212 }
2213 if anon_const_type.has_non_region_infer() {
2217 let e = self.dcx().span_err(
2218 const_arg.span(),
2219 "anonymous constants with inferred types are not yet supported",
2220 );
2221 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2222 return ty::Const::new_error(tcx, e);
2223 }
2224 if anon_const_type.has_non_region_param() {
2227 let e = self.dcx().span_err(
2228 const_arg.span(),
2229 "anonymous constants referencing generics are not yet supported",
2230 );
2231 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2232 return ty::Const::new_error(tcx, e);
2233 }
2234
2235 tcx.feed_anon_const_type(
2236 anon.def_id,
2237 ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2238 );
2239 }
2240
2241 let hir_id = const_arg.hir_id;
2242 match const_arg.kind {
2243 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2244 debug!(?maybe_qself, ?path);
2245 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2246 self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2247 }
2248 hir::ConstArgKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2249 debug!(?hir_self_ty, ?segment);
2250 let self_ty = self.lower_ty(hir_self_ty);
2251 self.lower_type_relative_const_path(
2252 self_ty,
2253 hir_self_ty,
2254 segment,
2255 hir_id,
2256 const_arg.span(),
2257 )
2258 .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2259 }
2260 hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
2261 ty::Const::new_error_with_message(
2262 tcx,
2263 qpath.span(),
2264 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
2265 )
2266 }
2267 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2268 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2269 }
2270 }
2271
2272 fn lower_resolved_const_path(
2274 &self,
2275 opt_self_ty: Option<Ty<'tcx>>,
2276 path: &hir::Path<'tcx>,
2277 hir_id: HirId,
2278 ) -> Const<'tcx> {
2279 let tcx = self.tcx();
2280 let span = path.span;
2281 match path.res {
2282 Res::Def(DefKind::ConstParam, def_id) => {
2283 assert_eq!(opt_self_ty, None);
2284 let _ = self.prohibit_generic_args(
2285 path.segments.iter(),
2286 GenericsArgsErrExtend::Param(def_id),
2287 );
2288 self.lower_const_param(def_id, hir_id)
2289 }
2290 Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2291 assert_eq!(opt_self_ty, None);
2292 let _ = self.prohibit_generic_args(
2293 path.segments.split_last().unwrap().1.iter(),
2294 GenericsArgsErrExtend::None,
2295 );
2296 let args = self.lower_generic_args_of_path_segment(
2297 span,
2298 did,
2299 path.segments.last().unwrap(),
2300 );
2301 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2302 }
2303 Res::Def(DefKind::AssocConst, did) => {
2304 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2305 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2306 Some(trait_)
2307 } else {
2308 None
2309 };
2310 self.lower_resolved_assoc_const_path(
2311 span,
2312 opt_self_ty,
2313 did,
2314 trait_segment,
2315 path.segments.last().unwrap(),
2316 )
2317 }
2318 Res::Def(DefKind::Static { .. }, _) => {
2319 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2320 }
2321 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2323 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2324 let args = self.lower_generic_args_of_path_segment(
2325 span,
2326 did,
2327 path.segments.last().unwrap(),
2328 );
2329 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2330 }
2331
2332 res @ (Res::Def(
2335 DefKind::Mod
2336 | DefKind::Enum
2337 | DefKind::Variant
2338 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2339 | DefKind::Struct
2340 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2341 | DefKind::OpaqueTy
2342 | DefKind::TyAlias
2343 | DefKind::TraitAlias
2344 | DefKind::AssocTy
2345 | DefKind::Union
2346 | DefKind::Trait
2347 | DefKind::ForeignTy
2348 | DefKind::TyParam
2349 | DefKind::Macro(_)
2350 | DefKind::LifetimeParam
2351 | DefKind::Use
2352 | DefKind::ForeignMod
2353 | DefKind::AnonConst
2354 | DefKind::InlineConst
2355 | DefKind::Field
2356 | DefKind::Impl { .. }
2357 | DefKind::Closure
2358 | DefKind::ExternCrate
2359 | DefKind::GlobalAsm
2360 | DefKind::SyntheticCoroutineBody,
2361 _,
2362 )
2363 | Res::PrimTy(_)
2364 | Res::SelfTyParam { .. }
2365 | Res::SelfTyAlias { .. }
2366 | Res::SelfCtor(_)
2367 | Res::Local(_)
2368 | Res::ToolMod
2369 | Res::NonMacroAttr(_)
2370 | Res::Err) => Const::new_error_with_message(
2371 tcx,
2372 span,
2373 format!("invalid Res {res:?} for const path"),
2374 ),
2375 }
2376 }
2377
2378 #[instrument(skip(self), level = "debug")]
2380 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2381 let tcx = self.tcx();
2382
2383 let expr = &tcx.hir_body(anon.body).value;
2384 debug!(?expr);
2385
2386 let ty = tcx.type_of(anon.def_id).instantiate_identity();
2390
2391 match self.try_lower_anon_const_lit(ty, expr) {
2392 Some(v) => v,
2393 None => ty::Const::new_unevaluated(
2394 tcx,
2395 ty::UnevaluatedConst {
2396 def: anon.def_id.to_def_id(),
2397 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2398 },
2399 ),
2400 }
2401 }
2402
2403 #[instrument(skip(self), level = "debug")]
2404 fn try_lower_anon_const_lit(
2405 &self,
2406 ty: Ty<'tcx>,
2407 expr: &'tcx hir::Expr<'tcx>,
2408 ) -> Option<Const<'tcx>> {
2409 let tcx = self.tcx();
2410
2411 let expr = match &expr.kind {
2414 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2415 block.expr.as_ref().unwrap()
2416 }
2417 _ => expr,
2418 };
2419
2420 if let hir::ExprKind::Path(hir::QPath::Resolved(
2421 _,
2422 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2423 )) = expr.kind
2424 {
2425 span_bug!(
2426 expr.span,
2427 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2428 );
2429 };
2430
2431 let lit_input = match expr.kind {
2432 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
2433 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2434 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
2435 _ => None,
2436 },
2437 _ => None,
2438 };
2439
2440 lit_input
2441 .filter(|l| !l.ty.has_aliases())
2444 .map(|l| tcx.at(expr.span).lit_to_const(l))
2445 }
2446
2447 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2448 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2449 match idx {
2450 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2451 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2452 }
2453 }
2454
2455 #[instrument(level = "debug", skip(self), ret)]
2457 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2458 let tcx = self.tcx();
2459
2460 let result_ty = match &hir_ty.kind {
2461 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2462 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2463 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2464 hir::TyKind::Ref(region, mt) => {
2465 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2466 debug!(?r);
2467 let t = self.lower_ty(mt.ty);
2468 Ty::new_ref(tcx, r, t, mt.mutbl)
2469 }
2470 hir::TyKind::Never => tcx.types.never,
2471 hir::TyKind::Tup(fields) => {
2472 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2473 }
2474 hir::TyKind::BareFn(bf) => {
2475 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span);
2476
2477 Ty::new_fn_ptr(
2478 tcx,
2479 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2480 )
2481 }
2482 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2483 tcx,
2484 ty::Binder::bind_with_vars(
2485 self.lower_ty(binder.inner_ty),
2486 tcx.late_bound_vars(hir_ty.hir_id),
2487 ),
2488 ),
2489 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2490 let lifetime = tagged_ptr.pointer();
2491 let repr = tagged_ptr.tag();
2492
2493 if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2494 Ty::new_error(tcx, guar)
2498 } else {
2499 let repr = match repr {
2500 TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2501 TraitObjectSyntax::DynStar => ty::DynStar,
2502 };
2503 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2504 }
2505 }
2506 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2510 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2511 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2512 }) =>
2513 {
2514 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2515 Ty::new_error(tcx, guar)
2516 }
2517 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2518 debug!(?maybe_qself, ?path);
2519 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2520 self.lower_resolved_ty_path(opt_self_ty, path, hir_ty.hir_id, PermitVariants::No)
2521 }
2522 &hir::TyKind::OpaqueDef(opaque_ty) => {
2523 let in_trait = match opaque_ty.origin {
2527 hir::OpaqueTyOrigin::FnReturn {
2528 in_trait_or_impl: Some(hir::RpitContext::Trait),
2529 ..
2530 }
2531 | hir::OpaqueTyOrigin::AsyncFn {
2532 in_trait_or_impl: Some(hir::RpitContext::Trait),
2533 ..
2534 } => true,
2535 hir::OpaqueTyOrigin::FnReturn {
2536 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2537 ..
2538 }
2539 | hir::OpaqueTyOrigin::AsyncFn {
2540 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2541 ..
2542 }
2543 | hir::OpaqueTyOrigin::TyAlias { .. } => false,
2544 };
2545
2546 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2547 }
2548 hir::TyKind::TraitAscription(hir_bounds) => {
2549 let self_ty = self.ty_infer(None, hir_ty.span);
2552 let mut bounds = Vec::new();
2553 self.lower_bounds(
2554 self_ty,
2555 hir_bounds.iter(),
2556 &mut bounds,
2557 ty::List::empty(),
2558 PredicateFilter::All,
2559 );
2560 self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2561 self_ty
2562 }
2563 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2567 if segment.args.is_some_and(|args| {
2568 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2569 }) =>
2570 {
2571 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2572 Ty::new_error(tcx, guar)
2573 }
2574 hir::TyKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2575 debug!(?hir_self_ty, ?segment);
2576 let self_ty = self.lower_ty(hir_self_ty);
2577 self.lower_type_relative_ty_path(
2578 self_ty,
2579 hir_self_ty,
2580 segment,
2581 hir_ty.hir_id,
2582 hir_ty.span,
2583 PermitVariants::No,
2584 )
2585 .map(|(ty, _, _)| ty)
2586 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2587 }
2588 &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
2589 let def_id = tcx.require_lang_item(lang_item, Some(span));
2590 let (args, _) = self.lower_generic_args_of_path(
2591 span,
2592 def_id,
2593 &[],
2594 &hir::PathSegment::invalid(),
2595 None,
2596 );
2597 tcx.at(span).type_of(def_id).instantiate(tcx, args)
2598 }
2599 hir::TyKind::Array(ty, length) => {
2600 let length = self.lower_const_arg(length, FeedConstTy::No);
2601 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2602 }
2603 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2604 hir::TyKind::Infer(()) => {
2605 self.ty_infer(None, hir_ty.span)
2610 }
2611 hir::TyKind::Pat(ty, pat) => {
2612 let ty_span = ty.span;
2613 let ty = self.lower_ty(ty);
2614 let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
2615 Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
2616 Err(guar) => Ty::new_error(tcx, guar),
2617 };
2618 self.record_ty(pat.hir_id, ty, pat.span);
2619 pat_ty
2620 }
2621 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2622 };
2623
2624 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2625 result_ty
2626 }
2627
2628 fn lower_pat_ty_pat(
2629 &self,
2630 ty: Ty<'tcx>,
2631 ty_span: Span,
2632 pat: &hir::TyPat<'tcx>,
2633 ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
2634 let tcx = self.tcx();
2635 match pat.kind {
2636 hir::TyPatKind::Range(start, end) => {
2637 match ty.kind() {
2638 ty::Int(_) | ty::Uint(_) | ty::Char => {
2641 let start = self.lower_const_arg(start, FeedConstTy::No);
2642 let end = self.lower_const_arg(end, FeedConstTy::No);
2643 Ok(ty::PatternKind::Range { start, end })
2644 }
2645 _ => Err(self
2646 .dcx()
2647 .span_delayed_bug(ty_span, "invalid base type for range pattern")),
2648 }
2649 }
2650 hir::TyPatKind::Or(patterns) => {
2651 self.tcx()
2652 .mk_patterns_from_iter(patterns.iter().map(|pat| {
2653 self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
2654 }))
2655 .map(ty::PatternKind::Or)
2656 }
2657 hir::TyPatKind::Err(e) => Err(e),
2658 }
2659 }
2660
2661 #[instrument(level = "debug", skip(self), ret)]
2663 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
2664 let tcx = self.tcx();
2665
2666 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2667 debug!(?lifetimes);
2668
2669 let def_id = if in_trait {
2673 tcx.associated_type_for_impl_trait_in_trait(def_id).to_def_id()
2674 } else {
2675 def_id.to_def_id()
2676 };
2677
2678 let generics = tcx.generics_of(def_id);
2679 debug!(?generics);
2680
2681 let offset = generics.count() - lifetimes.len();
2685
2686 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2687 if let Some(i) = (param.index as usize).checked_sub(offset) {
2688 let (lifetime, _) = lifetimes[i];
2689 self.lower_resolved_lifetime(lifetime).into()
2690 } else {
2691 tcx.mk_param_from_def(param)
2692 }
2693 });
2694 debug!(?args);
2695
2696 if in_trait {
2697 Ty::new_projection_from_args(tcx, def_id, args)
2698 } else {
2699 Ty::new_opaque(tcx, def_id, args)
2700 }
2701 }
2702
2703 pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
2704 match ty.kind {
2705 hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => {
2706 self.record_ty(ty.hir_id, expected_ty, ty.span);
2707 expected_ty
2708 }
2709 _ => self.lower_ty(ty),
2710 }
2711 }
2712
2713 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2715 pub fn lower_fn_ty(
2716 &self,
2717 hir_id: HirId,
2718 safety: hir::Safety,
2719 abi: rustc_abi::ExternAbi,
2720 decl: &hir::FnDecl<'tcx>,
2721 generics: Option<&hir::Generics<'_>>,
2722 hir_ty: Option<&hir::Ty<'_>>,
2723 ) -> ty::PolyFnSig<'tcx> {
2724 let tcx = self.tcx();
2725 let bound_vars = tcx.late_bound_vars(hir_id);
2726 debug!(?bound_vars);
2727
2728 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2729
2730 debug!(?output_ty);
2731
2732 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2733 let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2734
2735 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2736 tcx.hir_node(hir_id)
2737 {
2738 check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2739 }
2740
2741 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
2743
2744 if !bare_fn_ty.references_error() {
2745 let inputs = bare_fn_ty.inputs();
2752 let late_bound_in_args =
2753 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2754 let output = bare_fn_ty.output();
2755 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2756
2757 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2758 struct_span_code_err!(
2759 self.dcx(),
2760 decl.output.span(),
2761 E0581,
2762 "return type references {}, which is not constrained by the fn input types",
2763 br_name
2764 )
2765 });
2766 }
2767
2768 bare_fn_ty
2769 }
2770
2771 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2776 &self,
2777 fn_hir_id: HirId,
2778 arg_idx: Option<usize>,
2779 ) -> Option<Ty<'tcx>> {
2780 let tcx = self.tcx();
2781 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2782 tcx.hir_node(fn_hir_id)
2783 else {
2784 return None;
2785 };
2786 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2787
2788 let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
2789
2790 let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
2791 tcx,
2792 *ident,
2793 ty::AssocTag::Fn,
2794 trait_ref.def_id,
2795 )?;
2796
2797 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2798 tcx,
2799 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2800 );
2801 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2802
2803 Some(if let Some(arg_idx) = arg_idx {
2804 *fn_sig.inputs().get(arg_idx)?
2805 } else {
2806 fn_sig.output()
2807 })
2808 }
2809
2810 #[instrument(level = "trace", skip(self, generate_err))]
2811 fn validate_late_bound_regions<'cx>(
2812 &'cx self,
2813 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2814 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2815 generate_err: impl Fn(&str) -> Diag<'cx>,
2816 ) {
2817 for br in referenced_regions.difference(&constrained_regions) {
2818 let br_name = match *br {
2819 ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2820 | ty::BoundRegionKind::Anon
2821 | ty::BoundRegionKind::ClosureEnv => "an anonymous lifetime".to_string(),
2822 ty::BoundRegionKind::Named(_, name) => format!("lifetime `{name}`"),
2823 };
2824
2825 let mut err = generate_err(&br_name);
2826
2827 if let ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2828 | ty::BoundRegionKind::Anon = *br
2829 {
2830 err.note(
2837 "lifetimes appearing in an associated or opaque type are not considered constrained",
2838 );
2839 err.note("consider introducing a named lifetime parameter");
2840 }
2841
2842 err.emit();
2843 }
2844 }
2845
2846 #[instrument(level = "debug", skip(self, span), ret)]
2854 fn compute_object_lifetime_bound(
2855 &self,
2856 span: Span,
2857 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2858 ) -> Option<ty::Region<'tcx>> {
2860 let tcx = self.tcx();
2861
2862 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2865
2866 if derived_region_bounds.is_empty() {
2869 return None;
2870 }
2871
2872 if derived_region_bounds.iter().any(|r| r.is_static()) {
2875 return Some(tcx.lifetimes.re_static);
2876 }
2877
2878 let r = derived_region_bounds[0];
2882 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2883 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2884 }
2885 Some(r)
2886 }
2887}