1mod bounds;
17mod cmse;
18mod dyn_trait;
19pub mod errors;
20pub mod generics;
21
22use std::assert_matches::assert_matches;
23use std::slice;
24
25use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
26use rustc_errors::codes::*;
27use rustc_errors::{
28 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
29};
30use rustc_hir::attrs::AttributeKind;
31use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
32use rustc_hir::def_id::{DefId, LocalDefId};
33use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId, find_attr};
34use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
35use rustc_infer::traits::DynCompatibilityViolation;
36use rustc_macros::{TypeFoldable, TypeVisitable};
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, Ty, TyCtxt, TypeVisitableExt,
42 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, FulfillmentError};
51use tracing::{debug, instrument};
52
53use crate::check::check_abi;
54use crate::check_c_variadic_abi;
55use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation};
56use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
57use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
58use crate::middle::resolve_bound_vars as rbv;
59
60#[derive(Clone, Copy)]
63pub(crate) enum ImpliedBoundsContext<'tcx> {
64 TraitDef(LocalDefId),
67 TyParam(LocalDefId, &'tcx [hir::WherePredicate<'tcx>]),
69 AssociatedTypeOrImplTrait,
71}
72
73#[derive(Debug)]
75pub struct GenericPathSegment(pub DefId, pub usize);
76
77#[derive(Copy, Clone, Debug)]
78pub enum PredicateFilter {
79 All,
81
82 SelfOnly,
84
85 SelfTraitThatDefines(Ident),
89
90 SelfAndAssociatedTypeBounds,
94
95 ConstIfConst,
97
98 SelfConstIfConst,
100}
101
102#[derive(Debug)]
103pub enum RegionInferReason<'a> {
104 ExplicitObjectLifetime,
106 ObjectLifetimeDefault,
108 Param(&'a ty::GenericParamDef),
110 RegionPredicate,
111 Reference,
112 OutlivesBound,
113}
114
115#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Debug)]
116pub struct InherentAssocCandidate {
117 pub impl_: DefId,
118 pub assoc_item: DefId,
119 pub scope: DefId,
120}
121
122pub trait HirTyLowerer<'tcx> {
127 fn tcx(&self) -> TyCtxt<'tcx>;
128
129 fn dcx(&self) -> DiagCtxtHandle<'_>;
130
131 fn item_def_id(&self) -> LocalDefId;
133
134 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
136
137 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
139
140 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
142
143 fn register_trait_ascription_bounds(
144 &self,
145 bounds: Vec<(ty::Clause<'tcx>, Span)>,
146 hir_id: HirId,
147 span: Span,
148 );
149
150 fn probe_ty_param_bounds(
165 &self,
166 span: Span,
167 def_id: LocalDefId,
168 assoc_ident: Ident,
169 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
170
171 fn select_inherent_assoc_candidates(
172 &self,
173 span: Span,
174 self_ty: Ty<'tcx>,
175 candidates: Vec<InherentAssocCandidate>,
176 ) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>);
177
178 fn lower_assoc_item_path(
191 &self,
192 span: Span,
193 item_def_id: DefId,
194 item_segment: &hir::PathSegment<'tcx>,
195 poly_trait_ref: ty::PolyTraitRef<'tcx>,
196 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
197
198 fn lower_fn_sig(
199 &self,
200 decl: &hir::FnDecl<'tcx>,
201 generics: Option<&hir::Generics<'_>>,
202 hir_id: HirId,
203 hir_ty: Option<&hir::Ty<'_>>,
204 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
205
206 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
213
214 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
216
217 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
219
220 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
225 where
226 Self: Sized,
227 {
228 self
229 }
230
231 fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation>;
234}
235
236enum AssocItemQSelf {
240 Trait(DefId),
241 TyParam(LocalDefId, Span),
242 SelfTyAlias,
243}
244
245impl AssocItemQSelf {
246 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
247 match *self {
248 Self::Trait(def_id) => tcx.def_path_str(def_id),
249 Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
250 Self::SelfTyAlias => kw::SelfUpper.to_string(),
251 }
252 }
253}
254
255#[derive(Debug, Clone, Copy)]
262pub enum FeedConstTy<'a, 'tcx> {
263 Param(DefId, &'a [ty::GenericArg<'tcx>]),
271 No,
273}
274
275#[derive(Debug, Clone, Copy)]
276enum LowerTypeRelativePathMode {
277 Type(PermitVariants),
278 Const,
279}
280
281impl LowerTypeRelativePathMode {
282 fn assoc_tag(self) -> ty::AssocTag {
283 match self {
284 Self::Type(_) => ty::AssocTag::Type,
285 Self::Const => ty::AssocTag::Const,
286 }
287 }
288
289 fn def_kind(self) -> DefKind {
290 match self {
291 Self::Type(_) => DefKind::AssocTy,
292 Self::Const => DefKind::AssocConst,
293 }
294 }
295
296 fn permit_variants(self) -> PermitVariants {
297 match self {
298 Self::Type(permit_variants) => permit_variants,
299 Self::Const => PermitVariants::No,
302 }
303 }
304}
305
306#[derive(Debug, Clone, Copy)]
308pub enum PermitVariants {
309 Yes,
310 No,
311}
312
313#[derive(Debug, Clone, Copy)]
314enum TypeRelativePath<'tcx> {
315 AssocItem(DefId, GenericArgsRef<'tcx>),
316 Variant { adt: Ty<'tcx>, variant_did: DefId },
317}
318
319#[derive(Copy, Clone, PartialEq, Debug)]
329pub enum ExplicitLateBound {
330 Yes,
331 No,
332}
333
334#[derive(Copy, Clone, PartialEq)]
335pub enum IsMethodCall {
336 Yes,
337 No,
338}
339
340#[derive(Copy, Clone, PartialEq)]
343pub(crate) enum GenericArgPosition {
344 Type,
345 Value, MethodCall,
347}
348
349#[derive(Clone, Copy, Debug, PartialEq)]
353pub(crate) enum OverlappingAsssocItemConstraints {
354 Allowed,
355 Forbidden,
356}
357
358#[derive(Clone, Debug)]
361pub struct GenericArgCountMismatch {
362 pub reported: ErrorGuaranteed,
363 pub invalid_args: Vec<usize>,
365}
366
367#[derive(Clone, Debug)]
370pub struct GenericArgCountResult {
371 pub explicit_late_bound: ExplicitLateBound,
372 pub correct: Result<(), GenericArgCountMismatch>,
373}
374
375pub trait GenericArgsLowerer<'a, 'tcx> {
380 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
381
382 fn provided_kind(
383 &mut self,
384 preceding_args: &[ty::GenericArg<'tcx>],
385 param: &ty::GenericParamDef,
386 arg: &GenericArg<'tcx>,
387 ) -> ty::GenericArg<'tcx>;
388
389 fn inferred_kind(
390 &mut self,
391 preceding_args: &[ty::GenericArg<'tcx>],
392 param: &ty::GenericParamDef,
393 infer_args: bool,
394 ) -> ty::GenericArg<'tcx>;
395}
396
397impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
398 #[instrument(level = "debug", skip(self), ret)]
400 pub fn lower_lifetime(
401 &self,
402 lifetime: &hir::Lifetime,
403 reason: RegionInferReason<'_>,
404 ) -> ty::Region<'tcx> {
405 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
406 self.lower_resolved_lifetime(resolved)
407 } else {
408 self.re_infer(lifetime.ident.span, reason)
409 }
410 }
411
412 #[instrument(level = "debug", skip(self), ret)]
414 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
415 let tcx = self.tcx();
416
417 match resolved {
418 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
419
420 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
421 let br = ty::BoundRegion {
422 var: ty::BoundVar::from_u32(index),
423 kind: ty::BoundRegionKind::Named(def_id.to_def_id()),
424 };
425 ty::Region::new_bound(tcx, debruijn, br)
426 }
427
428 rbv::ResolvedArg::EarlyBound(def_id) => {
429 let name = tcx.hir_ty_param_name(def_id);
430 let item_def_id = tcx.hir_ty_param_owner(def_id);
431 let generics = tcx.generics_of(item_def_id);
432 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
433 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
434 }
435
436 rbv::ResolvedArg::Free(scope, id) => {
437 ty::Region::new_late_param(
438 tcx,
439 scope.to_def_id(),
440 ty::LateParamRegionKind::Named(id.to_def_id()),
441 )
442
443 }
445
446 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
447 }
448 }
449
450 pub fn lower_generic_args_of_path_segment(
451 &self,
452 span: Span,
453 def_id: DefId,
454 item_segment: &hir::PathSegment<'tcx>,
455 ) -> GenericArgsRef<'tcx> {
456 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
457 if let Some(c) = item_segment.args().constraints.first() {
458 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
459 }
460 args
461 }
462
463 #[instrument(level = "debug", skip(self, span), ret)]
498 fn lower_generic_args_of_path(
499 &self,
500 span: Span,
501 def_id: DefId,
502 parent_args: &[ty::GenericArg<'tcx>],
503 segment: &hir::PathSegment<'tcx>,
504 self_ty: Option<Ty<'tcx>>,
505 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
506 let tcx = self.tcx();
511 let generics = tcx.generics_of(def_id);
512 debug!(?generics);
513
514 if generics.has_self {
515 if generics.parent.is_some() {
516 assert!(!parent_args.is_empty())
519 } else {
520 assert!(self_ty.is_some());
522 }
523 } else {
524 assert!(self_ty.is_none());
525 }
526
527 let arg_count = check_generic_arg_count(
528 self,
529 def_id,
530 segment,
531 generics,
532 GenericArgPosition::Type,
533 self_ty.is_some(),
534 );
535
536 if generics.is_own_empty() {
541 return (tcx.mk_args(parent_args), arg_count);
542 }
543
544 struct GenericArgsCtxt<'a, 'tcx> {
545 lowerer: &'a dyn HirTyLowerer<'tcx>,
546 def_id: DefId,
547 generic_args: &'a GenericArgs<'tcx>,
548 span: Span,
549 infer_args: bool,
550 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
551 }
552
553 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
554 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
555 if did == self.def_id {
556 (Some(self.generic_args), self.infer_args)
557 } else {
558 (None, false)
560 }
561 }
562
563 fn provided_kind(
564 &mut self,
565 preceding_args: &[ty::GenericArg<'tcx>],
566 param: &ty::GenericParamDef,
567 arg: &GenericArg<'tcx>,
568 ) -> ty::GenericArg<'tcx> {
569 let tcx = self.lowerer.tcx();
570
571 if let Err(incorrect) = self.incorrect_args {
572 if incorrect.invalid_args.contains(&(param.index as usize)) {
573 return param.to_error(tcx);
574 }
575 }
576
577 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
578 if has_default {
579 tcx.check_optional_stability(
580 param.def_id,
581 Some(arg.hir_id()),
582 arg.span(),
583 None,
584 AllowUnstable::No,
585 |_, _| {
586 },
592 );
593 }
594 self.lowerer.lower_ty(ty).into()
595 };
596
597 match (¶m.kind, arg) {
598 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
599 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
600 }
601 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
602 handle_ty_args(has_default, ty.as_unambig_ty())
604 }
605 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
606 handle_ty_args(has_default, &inf.to_ty())
607 }
608 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
609 .lowerer
610 .lower_const_arg(
612 ct.as_unambig_ct(),
613 FeedConstTy::Param(param.def_id, preceding_args),
614 )
615 .into(),
616 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
617 self.lowerer.ct_infer(Some(param), inf.span).into()
618 }
619 (kind, arg) => span_bug!(
620 self.span,
621 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
622 ),
623 }
624 }
625
626 fn inferred_kind(
627 &mut self,
628 preceding_args: &[ty::GenericArg<'tcx>],
629 param: &ty::GenericParamDef,
630 infer_args: bool,
631 ) -> ty::GenericArg<'tcx> {
632 let tcx = self.lowerer.tcx();
633
634 if let Err(incorrect) = self.incorrect_args {
635 if incorrect.invalid_args.contains(&(param.index as usize)) {
636 return param.to_error(tcx);
637 }
638 }
639 match param.kind {
640 GenericParamDefKind::Lifetime => {
641 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
642 }
643 GenericParamDefKind::Type { has_default, .. } => {
644 if !infer_args && has_default {
645 if let Some(prev) =
647 preceding_args.iter().find_map(|arg| match arg.kind() {
648 GenericArgKind::Type(ty) => ty.error_reported().err(),
649 _ => None,
650 })
651 {
652 return Ty::new_error(tcx, prev).into();
654 }
655 tcx.at(self.span)
656 .type_of(param.def_id)
657 .instantiate(tcx, preceding_args)
658 .into()
659 } else if infer_args {
660 self.lowerer.ty_infer(Some(param), self.span).into()
661 } else {
662 Ty::new_misc_error(tcx).into()
664 }
665 }
666 GenericParamDefKind::Const { has_default, .. } => {
667 let ty = tcx
668 .at(self.span)
669 .type_of(param.def_id)
670 .instantiate(tcx, preceding_args);
671 if let Err(guar) = ty.error_reported() {
672 return ty::Const::new_error(tcx, guar).into();
673 }
674 if !infer_args && has_default {
675 tcx.const_param_default(param.def_id)
676 .instantiate(tcx, preceding_args)
677 .into()
678 } else if infer_args {
679 self.lowerer.ct_infer(Some(param), self.span).into()
680 } else {
681 ty::Const::new_misc_error(tcx).into()
683 }
684 }
685 }
686 }
687 }
688
689 let mut args_ctx = GenericArgsCtxt {
690 lowerer: self,
691 def_id,
692 span,
693 generic_args: segment.args(),
694 infer_args: segment.infer_args,
695 incorrect_args: &arg_count.correct,
696 };
697 let args = lower_generic_args(
698 self,
699 def_id,
700 parent_args,
701 self_ty.is_some(),
702 self_ty,
703 &arg_count,
704 &mut args_ctx,
705 );
706
707 (args, arg_count)
708 }
709
710 #[instrument(level = "debug", skip(self))]
711 pub fn lower_generic_args_of_assoc_item(
712 &self,
713 span: Span,
714 item_def_id: DefId,
715 item_segment: &hir::PathSegment<'tcx>,
716 parent_args: GenericArgsRef<'tcx>,
717 ) -> GenericArgsRef<'tcx> {
718 let (args, _) =
719 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
720 if let Some(c) = item_segment.args().constraints.first() {
721 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
722 }
723 args
724 }
725
726 pub fn lower_impl_trait_ref(
730 &self,
731 trait_ref: &hir::TraitRef<'tcx>,
732 self_ty: Ty<'tcx>,
733 ) -> ty::TraitRef<'tcx> {
734 let [leading_segments @ .., segment] = trait_ref.path.segments else { bug!() };
735
736 let _ = self.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
737
738 self.lower_mono_trait_ref(
739 trait_ref.path.span,
740 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
741 self_ty,
742 segment,
743 true,
744 )
745 }
746
747 #[instrument(level = "debug", skip(self, bounds))]
771 pub(crate) fn lower_poly_trait_ref(
772 &self,
773 &hir::PolyTraitRef {
774 bound_generic_params,
775 modifiers: hir::TraitBoundModifiers { constness, polarity },
776 trait_ref,
777 span,
778 }: &hir::PolyTraitRef<'tcx>,
779 self_ty: Ty<'tcx>,
780 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
781 predicate_filter: PredicateFilter,
782 overlapping_assoc_item_constraints: OverlappingAsssocItemConstraints,
783 ) -> GenericArgCountResult {
784 let tcx = self.tcx();
785
786 let _ = bound_generic_params;
789
790 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
791
792 let transient = match polarity {
797 hir::BoundPolarity::Positive => {
798 tcx.is_lang_item(trait_def_id, hir::LangItem::PointeeSized)
804 }
805 hir::BoundPolarity::Negative(_) => false,
806 hir::BoundPolarity::Maybe(_) => {
807 self.require_bound_to_relax_default_trait(trait_ref, span);
808 true
809 }
810 };
811 let bounds = if transient { &mut Vec::new() } else { bounds };
812
813 let polarity = match polarity {
814 hir::BoundPolarity::Positive | hir::BoundPolarity::Maybe(_) => {
815 ty::PredicatePolarity::Positive
816 }
817 hir::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
818 };
819
820 let [leading_segments @ .., segment] = trait_ref.path.segments else { bug!() };
821
822 let _ = self.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
823 self.report_internal_fn_trait(span, trait_def_id, segment, false);
824
825 let (generic_args, arg_count) = self.lower_generic_args_of_path(
826 trait_ref.path.span,
827 trait_def_id,
828 &[],
829 segment,
830 Some(self_ty),
831 );
832
833 let constraints = segment.args().constraints;
834
835 if transient && (!generic_args[1..].is_empty() || !constraints.is_empty()) {
836 self.dcx()
846 .span_delayed_bug(span, "transient bound should not have args or constraints");
847 }
848
849 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
850 debug!(?bound_vars);
851
852 let poly_trait_ref = ty::Binder::bind_with_vars(
853 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
854 bound_vars,
855 );
856
857 debug!(?poly_trait_ref);
858
859 match predicate_filter {
861 PredicateFilter::All
862 | PredicateFilter::SelfOnly
863 | PredicateFilter::SelfTraitThatDefines(..)
864 | PredicateFilter::SelfAndAssociatedTypeBounds => {
865 let bound = poly_trait_ref.map_bound(|trait_ref| {
866 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
867 });
868 let bound = (bound.upcast(tcx), span);
869 if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
875 bounds.insert(0, bound);
876 } else {
877 bounds.push(bound);
878 }
879 }
880 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
881 }
882
883 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
884 && !tcx.is_const_trait(trait_def_id)
885 {
886 let (def_span, suggestion, suggestion_pre) =
887 match (trait_def_id.as_local(), tcx.sess.is_nightly_build()) {
888 (Some(trait_def_id), true) => {
889 let span = tcx.hir_expect_item(trait_def_id).vis_span;
890 let span = tcx.sess.source_map().span_extend_while_whitespace(span);
891
892 (
893 None,
894 Some(span.shrink_to_hi()),
895 if self.tcx().features().const_trait_impl() {
896 ""
897 } else {
898 "enable `#![feature(const_trait_impl)]` in your crate and "
899 },
900 )
901 }
902 (None, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
903 };
904 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
905 span,
906 modifier: constness.as_str(),
907 def_span,
908 trait_name: tcx.def_path_str(trait_def_id),
909 suggestion,
910 suggestion_pre,
911 });
912 } else {
913 match predicate_filter {
914 PredicateFilter::SelfTraitThatDefines(..) => {}
916 PredicateFilter::All
917 | PredicateFilter::SelfOnly
918 | PredicateFilter::SelfAndAssociatedTypeBounds => {
919 match constness {
920 hir::BoundConstness::Always(_) => {
921 if polarity == ty::PredicatePolarity::Positive {
922 bounds.push((
923 poly_trait_ref
924 .to_host_effect_clause(tcx, ty::BoundConstness::Const),
925 span,
926 ));
927 }
928 }
929 hir::BoundConstness::Maybe(_) => {
930 }
935 hir::BoundConstness::Never => {}
936 }
937 }
938 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
945 match constness {
946 hir::BoundConstness::Maybe(_) => {
947 if polarity == ty::PredicatePolarity::Positive {
948 bounds.push((
949 poly_trait_ref
950 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
951 span,
952 ));
953 }
954 }
955 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
956 }
957 }
958 }
959 }
960
961 let mut dup_constraints = (overlapping_assoc_item_constraints
962 == OverlappingAsssocItemConstraints::Forbidden)
963 .then_some(FxIndexMap::default());
964
965 for constraint in constraints {
966 if polarity == ty::PredicatePolarity::Negative {
970 self.dcx().span_delayed_bug(
971 constraint.span,
972 "negative trait bounds should not have assoc item constraints",
973 );
974 break;
975 }
976
977 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
979 trait_ref.hir_ref_id,
980 poly_trait_ref,
981 constraint,
982 bounds,
983 dup_constraints.as_mut(),
984 constraint.span,
985 predicate_filter,
986 );
987 }
989
990 arg_count
991 }
992
993 fn lower_mono_trait_ref(
997 &self,
998 span: Span,
999 trait_def_id: DefId,
1000 self_ty: Ty<'tcx>,
1001 trait_segment: &hir::PathSegment<'tcx>,
1002 is_impl: bool,
1003 ) -> ty::TraitRef<'tcx> {
1004 self.report_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
1005
1006 let (generic_args, _) =
1007 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
1008 if let Some(c) = trait_segment.args().constraints.first() {
1009 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
1010 }
1011 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
1012 }
1013
1014 fn probe_trait_that_defines_assoc_item(
1015 &self,
1016 trait_def_id: DefId,
1017 assoc_tag: ty::AssocTag,
1018 assoc_ident: Ident,
1019 ) -> bool {
1020 self.tcx()
1021 .associated_items(trait_def_id)
1022 .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
1023 .is_some()
1024 }
1025
1026 fn lower_path_segment(
1027 &self,
1028 span: Span,
1029 did: DefId,
1030 item_segment: &hir::PathSegment<'tcx>,
1031 ) -> Ty<'tcx> {
1032 let tcx = self.tcx();
1033 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
1034
1035 if let DefKind::TyAlias = tcx.def_kind(did)
1036 && tcx.type_alias_is_lazy(did)
1037 {
1038 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
1042 Ty::new_alias(tcx, ty::Free, alias_ty)
1043 } else {
1044 tcx.at(span).type_of(did).instantiate(tcx, args)
1045 }
1046 }
1047
1048 #[instrument(level = "debug", skip_all, ret)]
1056 fn probe_single_ty_param_bound_for_assoc_item(
1057 &self,
1058 ty_param_def_id: LocalDefId,
1059 ty_param_span: Span,
1060 assoc_tag: ty::AssocTag,
1061 assoc_ident: Ident,
1062 span: Span,
1063 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
1064 debug!(?ty_param_def_id, ?assoc_ident, ?span);
1065 let tcx = self.tcx();
1066
1067 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
1068 debug!("predicates={:#?}", predicates);
1069
1070 self.probe_single_bound_for_assoc_item(
1071 || {
1072 let trait_refs = predicates
1073 .iter_identity_copied()
1074 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
1075 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
1076 },
1077 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
1078 assoc_tag,
1079 assoc_ident,
1080 span,
1081 None,
1082 )
1083 }
1084
1085 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1091 fn probe_single_bound_for_assoc_item<I>(
1092 &self,
1093 all_candidates: impl Fn() -> I,
1094 qself: AssocItemQSelf,
1095 assoc_tag: ty::AssocTag,
1096 assoc_ident: Ident,
1097 span: Span,
1098 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1099 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1100 where
1101 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1102 {
1103 let tcx = self.tcx();
1104
1105 let mut matching_candidates = all_candidates().filter(|r| {
1106 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
1107 });
1108
1109 let Some(bound) = matching_candidates.next() else {
1110 return Err(self.report_unresolved_assoc_item(
1111 all_candidates,
1112 qself,
1113 assoc_tag,
1114 assoc_ident,
1115 span,
1116 constraint,
1117 ));
1118 };
1119 debug!(?bound);
1120
1121 if let Some(bound2) = matching_candidates.next() {
1122 debug!(?bound2);
1123
1124 let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
1125 let qself_str = qself.to_string(tcx);
1126 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1127 span,
1128 assoc_kind: assoc_kind_str,
1129 assoc_ident,
1130 qself: &qself_str,
1131 });
1132 err.code(
1134 if let Some(constraint) = constraint
1135 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1136 {
1137 E0222
1138 } else {
1139 E0221
1140 },
1141 );
1142
1143 let mut where_bounds = vec![];
1147 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1148 let bound_id = bound.def_id();
1149 let bound_span = tcx
1150 .associated_items(bound_id)
1151 .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1152 .and_then(|item| tcx.hir_span_if_local(item.def_id));
1153
1154 if let Some(bound_span) = bound_span {
1155 err.span_label(
1156 bound_span,
1157 format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
1158 );
1159 if let Some(constraint) = constraint {
1160 match constraint.kind {
1161 hir::AssocItemConstraintKind::Equality { term } => {
1162 let term: ty::Term<'_> = match term {
1163 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1164 hir::Term::Const(ct) => {
1165 self.lower_const_arg(ct, FeedConstTy::No).into()
1166 }
1167 };
1168 if term.references_error() {
1169 continue;
1170 }
1171 where_bounds.push(format!(
1173 " T: {trait}::{assoc_ident} = {term}",
1174 trait = bound.print_only_trait_path(),
1175 ));
1176 }
1177 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1179 }
1180 } else {
1181 err.span_suggestion_verbose(
1182 span.with_hi(assoc_ident.span.lo()),
1183 "use fully-qualified syntax to disambiguate",
1184 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1185 Applicability::MaybeIncorrect,
1186 );
1187 }
1188 } else {
1189 let trait_ =
1190 tcx.short_string(bound.print_only_trait_path(), err.long_ty_path());
1191 err.note(format!(
1192 "associated {assoc_kind_str} `{assoc_ident}` could derive from `{trait_}`",
1193 ));
1194 }
1195 }
1196 if !where_bounds.is_empty() {
1197 err.help(format!(
1198 "consider introducing a new type parameter `T` and adding `where` constraints:\
1199 \n where\n T: {qself_str},\n{}",
1200 where_bounds.join(",\n"),
1201 ));
1202 let reported = err.emit();
1203 return Err(reported);
1204 }
1205 err.emit();
1206 }
1207
1208 Ok(bound)
1209 }
1210
1211 #[instrument(level = "debug", skip_all, ret)]
1238 pub fn lower_type_relative_ty_path(
1239 &self,
1240 self_ty: Ty<'tcx>,
1241 hir_self_ty: &'tcx hir::Ty<'tcx>,
1242 segment: &'tcx hir::PathSegment<'tcx>,
1243 qpath_hir_id: HirId,
1244 span: Span,
1245 permit_variants: PermitVariants,
1246 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1247 let tcx = self.tcx();
1248 match self.lower_type_relative_path(
1249 self_ty,
1250 hir_self_ty,
1251 segment,
1252 qpath_hir_id,
1253 span,
1254 LowerTypeRelativePathMode::Type(permit_variants),
1255 )? {
1256 TypeRelativePath::AssocItem(def_id, args) => {
1257 let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1258 let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1259 Ok((ty, tcx.def_kind(def_id), def_id))
1260 }
1261 TypeRelativePath::Variant { adt, variant_did } => {
1262 Ok((adt, DefKind::Variant, variant_did))
1263 }
1264 }
1265 }
1266
1267 #[instrument(level = "debug", skip_all, ret)]
1269 fn lower_type_relative_const_path(
1270 &self,
1271 self_ty: Ty<'tcx>,
1272 hir_self_ty: &'tcx hir::Ty<'tcx>,
1273 segment: &'tcx hir::PathSegment<'tcx>,
1274 qpath_hir_id: HirId,
1275 span: Span,
1276 ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1277 let tcx = self.tcx();
1278 let (def_id, args) = match self.lower_type_relative_path(
1279 self_ty,
1280 hir_self_ty,
1281 segment,
1282 qpath_hir_id,
1283 span,
1284 LowerTypeRelativePathMode::Const,
1285 )? {
1286 TypeRelativePath::AssocItem(def_id, args) => {
1287 if !find_attr!(self.tcx().get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
1288 let mut err = self.dcx().struct_span_err(
1289 span,
1290 "use of trait associated const without `#[type_const]`",
1291 );
1292 err.note("the declaration in the trait must be marked with `#[type_const]`");
1293 return Err(err.emit());
1294 }
1295 (def_id, args)
1296 }
1297 TypeRelativePath::Variant { .. } => {
1300 span_bug!(span, "unexpected variant res for type associated const path")
1301 }
1302 };
1303 Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
1304 }
1305
1306 #[instrument(level = "debug", skip_all, ret)]
1308 fn lower_type_relative_path(
1309 &self,
1310 self_ty: Ty<'tcx>,
1311 hir_self_ty: &'tcx hir::Ty<'tcx>,
1312 segment: &'tcx hir::PathSegment<'tcx>,
1313 qpath_hir_id: HirId,
1314 span: Span,
1315 mode: LowerTypeRelativePathMode,
1316 ) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
1317 debug!(%self_ty, ?segment.ident);
1318 let tcx = self.tcx();
1319
1320 let mut variant_def_id = None;
1322 if let Some(adt_def) = self.probe_adt(span, self_ty) {
1323 if adt_def.is_enum() {
1324 let variant_def = adt_def
1325 .variants()
1326 .iter()
1327 .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
1328 if let Some(variant_def) = variant_def {
1329 if let PermitVariants::Yes = mode.permit_variants() {
1330 tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1331 let _ = self.prohibit_generic_args(
1332 slice::from_ref(segment).iter(),
1333 GenericsArgsErrExtend::EnumVariant {
1334 qself: hir_self_ty,
1335 assoc_segment: segment,
1336 adt_def,
1337 },
1338 );
1339 return Ok(TypeRelativePath::Variant {
1340 adt: self_ty,
1341 variant_did: variant_def.def_id,
1342 });
1343 } else {
1344 variant_def_id = Some(variant_def.def_id);
1345 }
1346 }
1347 }
1348
1349 if let Some((did, args)) = self.probe_inherent_assoc_item(
1351 segment,
1352 adt_def.did(),
1353 self_ty,
1354 qpath_hir_id,
1355 span,
1356 mode.assoc_tag(),
1357 )? {
1358 return Ok(TypeRelativePath::AssocItem(did, args));
1359 }
1360 }
1361
1362 let (item_def_id, bound) = self.resolve_type_relative_path(
1363 self_ty,
1364 hir_self_ty,
1365 mode.assoc_tag(),
1366 segment,
1367 qpath_hir_id,
1368 span,
1369 variant_def_id,
1370 )?;
1371
1372 let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
1373
1374 if let Some(variant_def_id) = variant_def_id {
1375 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
1376 lint.primary_message("ambiguous associated item");
1377 let mut could_refer_to = |kind: DefKind, def_id, also| {
1378 let note_msg = format!(
1379 "`{}` could{} refer to the {} defined here",
1380 segment.ident,
1381 also,
1382 tcx.def_kind_descr(kind, def_id)
1383 );
1384 lint.span_note(tcx.def_span(def_id), note_msg);
1385 };
1386
1387 could_refer_to(DefKind::Variant, variant_def_id, "");
1388 could_refer_to(mode.def_kind(), item_def_id, " also");
1389
1390 lint.span_suggestion(
1391 span,
1392 "use fully-qualified syntax",
1393 format!(
1394 "<{} as {}>::{}",
1395 self_ty,
1396 tcx.item_name(bound.def_id()),
1397 segment.ident
1398 ),
1399 Applicability::MachineApplicable,
1400 );
1401 });
1402 }
1403
1404 Ok(TypeRelativePath::AssocItem(item_def_id, args))
1405 }
1406
1407 fn resolve_type_relative_path(
1409 &self,
1410 self_ty: Ty<'tcx>,
1411 hir_self_ty: &'tcx hir::Ty<'tcx>,
1412 assoc_tag: ty::AssocTag,
1413 segment: &'tcx hir::PathSegment<'tcx>,
1414 qpath_hir_id: HirId,
1415 span: Span,
1416 variant_def_id: Option<DefId>,
1417 ) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
1418 let tcx = self.tcx();
1419
1420 let self_ty_res = match hir_self_ty.kind {
1421 hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
1422 _ => Res::Err,
1423 };
1424
1425 let bound = match (self_ty.kind(), self_ty_res) {
1427 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1428 let trait_ref = tcx.impl_trait_ref(impl_def_id);
1431
1432 self.probe_single_bound_for_assoc_item(
1433 || {
1434 let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
1435 traits::supertraits(tcx, trait_ref)
1436 },
1437 AssocItemQSelf::SelfTyAlias,
1438 assoc_tag,
1439 segment.ident,
1440 span,
1441 None,
1442 )?
1443 }
1444 (
1445 &ty::Param(_),
1446 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1447 ) => self.probe_single_ty_param_bound_for_assoc_item(
1448 param_did.expect_local(),
1449 hir_self_ty.span,
1450 assoc_tag,
1451 segment.ident,
1452 span,
1453 )?,
1454 _ => {
1455 return Err(self.report_unresolved_type_relative_path(
1456 self_ty,
1457 hir_self_ty,
1458 assoc_tag,
1459 segment.ident,
1460 qpath_hir_id,
1461 span,
1462 variant_def_id,
1463 ));
1464 }
1465 };
1466
1467 let assoc_item = self
1468 .probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
1469 .expect("failed to find associated item");
1470
1471 Ok((assoc_item.def_id, bound))
1472 }
1473
1474 fn probe_inherent_assoc_item(
1476 &self,
1477 segment: &hir::PathSegment<'tcx>,
1478 adt_did: DefId,
1479 self_ty: Ty<'tcx>,
1480 block: HirId,
1481 span: Span,
1482 assoc_tag: ty::AssocTag,
1483 ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1484 let tcx = self.tcx();
1485
1486 if !tcx.features().inherent_associated_types() {
1487 match assoc_tag {
1488 ty::AssocTag::Type => return Ok(None),
1493 ty::AssocTag::Const => {
1494 return Err(feature_err(
1498 &tcx.sess,
1499 sym::inherent_associated_types,
1500 span,
1501 "inherent associated types are unstable",
1502 )
1503 .emit());
1504 }
1505 ty::AssocTag::Fn => unreachable!(),
1506 }
1507 }
1508
1509 let name = segment.ident;
1510 let candidates: Vec<_> = tcx
1511 .inherent_impls(adt_did)
1512 .iter()
1513 .filter_map(|&impl_| {
1514 let (item, scope) =
1515 self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1516 Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope })
1517 })
1518 .collect();
1519
1520 if candidates.is_empty() {
1525 return Ok(None);
1526 }
1527
1528 let (applicable_candidates, fulfillment_errors) =
1529 self.select_inherent_assoc_candidates(span, self_ty, candidates.clone());
1530
1531 let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } =
1533 match &applicable_candidates[..] {
1534 &[] => Err(self.report_unresolved_inherent_assoc_item(
1535 name,
1536 self_ty,
1537 candidates,
1538 fulfillment_errors,
1539 span,
1540 assoc_tag,
1541 )),
1542
1543 &[applicable_candidate] => Ok(applicable_candidate),
1544
1545 &[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
1546 name,
1547 candidates.into_iter().map(|cand| cand.assoc_item).collect(),
1548 span,
1549 )),
1550 }?;
1551
1552 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1555
1556 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1560 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1561 let args = tcx.mk_args_from_iter(
1562 std::iter::once(ty::GenericArg::from(self_ty))
1563 .chain(args.into_iter().skip(parent_args.len())),
1564 );
1565
1566 Ok(Some((assoc_item, args)))
1567 }
1568
1569 fn probe_assoc_item(
1573 &self,
1574 ident: Ident,
1575 assoc_tag: ty::AssocTag,
1576 block: HirId,
1577 span: Span,
1578 scope: DefId,
1579 ) -> Option<ty::AssocItem> {
1580 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1581 self.check_assoc_item(item.def_id, ident, scope, block, span);
1582 Some(item)
1583 }
1584
1585 fn probe_assoc_item_unchecked(
1590 &self,
1591 ident: Ident,
1592 assoc_tag: ty::AssocTag,
1593 block: HirId,
1594 scope: DefId,
1595 ) -> Option<(ty::AssocItem, DefId)> {
1596 let tcx = self.tcx();
1597
1598 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1599 let item = tcx
1603 .associated_items(scope)
1604 .filter_by_name_unhygienic(ident.name)
1605 .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1606
1607 Some((*item, def_scope))
1608 }
1609
1610 fn check_assoc_item(
1612 &self,
1613 item_def_id: DefId,
1614 ident: Ident,
1615 scope: DefId,
1616 block: HirId,
1617 span: Span,
1618 ) {
1619 let tcx = self.tcx();
1620
1621 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1622 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1623 span,
1624 kind: tcx.def_descr(item_def_id),
1625 name: ident,
1626 defined_here_label: tcx.def_span(item_def_id),
1627 });
1628 }
1629
1630 tcx.check_stability(item_def_id, Some(block), span, None);
1631 }
1632
1633 fn probe_traits_that_match_assoc_ty(
1634 &self,
1635 qself_ty: Ty<'tcx>,
1636 assoc_ident: Ident,
1637 ) -> Vec<String> {
1638 let tcx = self.tcx();
1639
1640 let infcx_;
1643 let infcx = if let Some(infcx) = self.infcx() {
1644 infcx
1645 } else {
1646 assert!(!qself_ty.has_infer());
1647 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1648 &infcx_
1649 };
1650
1651 tcx.all_traits_including_private()
1652 .filter(|trait_def_id| {
1653 tcx.associated_items(*trait_def_id)
1655 .in_definition_order()
1656 .any(|i| {
1657 i.is_type()
1658 && !i.is_impl_trait_in_trait()
1659 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1660 })
1661 && tcx.visibility(*trait_def_id)
1663 .is_accessible_from(self.item_def_id(), tcx)
1664 && tcx.all_impls(*trait_def_id)
1665 .any(|impl_def_id| {
1666 let header = tcx.impl_trait_header(impl_def_id);
1667 let trait_ref = header.trait_ref.instantiate(
1668 tcx,
1669 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1670 );
1671
1672 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1673 if value.has_escaping_bound_vars() {
1675 return false;
1676 }
1677 infcx
1678 .can_eq(
1679 ty::ParamEnv::empty(),
1680 trait_ref.self_ty(),
1681 value,
1682 ) && header.polarity != ty::ImplPolarity::Negative
1683 })
1684 })
1685 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1686 .collect()
1687 }
1688
1689 #[instrument(level = "debug", skip_all)]
1691 fn lower_resolved_assoc_ty_path(
1692 &self,
1693 span: Span,
1694 opt_self_ty: Option<Ty<'tcx>>,
1695 item_def_id: DefId,
1696 trait_segment: Option<&hir::PathSegment<'tcx>>,
1697 item_segment: &hir::PathSegment<'tcx>,
1698 ) -> Ty<'tcx> {
1699 match self.lower_resolved_assoc_item_path(
1700 span,
1701 opt_self_ty,
1702 item_def_id,
1703 trait_segment,
1704 item_segment,
1705 ty::AssocTag::Type,
1706 ) {
1707 Ok((item_def_id, item_args)) => {
1708 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1709 }
1710 Err(guar) => Ty::new_error(self.tcx(), guar),
1711 }
1712 }
1713
1714 #[instrument(level = "debug", skip_all)]
1716 fn lower_resolved_assoc_const_path(
1717 &self,
1718 span: Span,
1719 opt_self_ty: Option<Ty<'tcx>>,
1720 item_def_id: DefId,
1721 trait_segment: Option<&hir::PathSegment<'tcx>>,
1722 item_segment: &hir::PathSegment<'tcx>,
1723 ) -> Const<'tcx> {
1724 match self.lower_resolved_assoc_item_path(
1725 span,
1726 opt_self_ty,
1727 item_def_id,
1728 trait_segment,
1729 item_segment,
1730 ty::AssocTag::Const,
1731 ) {
1732 Ok((item_def_id, item_args)) => {
1733 if !find_attr!(self.tcx().get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) {
1734 let mut err = self.dcx().struct_span_err(
1735 span,
1736 "use of `const` in the type system without `#[type_const]`",
1737 );
1738 err.note("the declaration must be marked with `#[type_const]`");
1739 return Const::new_error(self.tcx(), err.emit());
1740 }
1741
1742 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1743 Const::new_unevaluated(self.tcx(), uv)
1744 }
1745 Err(guar) => Const::new_error(self.tcx(), guar),
1746 }
1747 }
1748
1749 #[instrument(level = "debug", skip_all)]
1751 fn lower_resolved_assoc_item_path(
1752 &self,
1753 span: Span,
1754 opt_self_ty: Option<Ty<'tcx>>,
1755 item_def_id: DefId,
1756 trait_segment: Option<&hir::PathSegment<'tcx>>,
1757 item_segment: &hir::PathSegment<'tcx>,
1758 assoc_tag: ty::AssocTag,
1759 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1760 let tcx = self.tcx();
1761
1762 let trait_def_id = tcx.parent(item_def_id);
1763 debug!(?trait_def_id);
1764
1765 let Some(self_ty) = opt_self_ty else {
1766 return Err(self.report_missing_self_ty_for_resolved_path(
1767 trait_def_id,
1768 span,
1769 item_segment,
1770 assoc_tag,
1771 ));
1772 };
1773 debug!(?self_ty);
1774
1775 let trait_ref =
1776 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
1777 debug!(?trait_ref);
1778
1779 let item_args =
1780 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1781
1782 Ok((item_def_id, item_args))
1783 }
1784
1785 pub fn prohibit_generic_args<'a>(
1786 &self,
1787 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1788 err_extend: GenericsArgsErrExtend<'a>,
1789 ) -> Result<(), ErrorGuaranteed> {
1790 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1791 let mut result = Ok(());
1792 if let Some(_) = args_visitors.clone().next() {
1793 result = Err(self.report_prohibited_generic_args(
1794 segments.clone(),
1795 args_visitors,
1796 err_extend,
1797 ));
1798 }
1799
1800 for segment in segments {
1801 if let Some(c) = segment.args().constraints.first() {
1803 return Err(prohibit_assoc_item_constraint(self, c, None));
1804 }
1805 }
1806
1807 result
1808 }
1809
1810 pub fn probe_generic_path_segments(
1828 &self,
1829 segments: &[hir::PathSegment<'_>],
1830 self_ty: Option<Ty<'tcx>>,
1831 kind: DefKind,
1832 def_id: DefId,
1833 span: Span,
1834 ) -> Vec<GenericPathSegment> {
1835 let tcx = self.tcx();
1881
1882 assert!(!segments.is_empty());
1883 let last = segments.len() - 1;
1884
1885 let mut generic_segments = vec![];
1886
1887 match kind {
1888 DefKind::Ctor(CtorOf::Struct, ..) => {
1890 let generics = tcx.generics_of(def_id);
1893 let generics_def_id = generics.parent.unwrap_or(def_id);
1896 generic_segments.push(GenericPathSegment(generics_def_id, last));
1897 }
1898
1899 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
1901 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
1902 let adt_def = self.probe_adt(span, self_ty).unwrap();
1903 debug_assert!(adt_def.is_enum());
1904 (adt_def.did(), last)
1905 } else if last >= 1 && segments[last - 1].args.is_some() {
1906 let mut def_id = def_id;
1909
1910 if let DefKind::Ctor(..) = kind {
1912 def_id = tcx.parent(def_id);
1913 }
1914
1915 let enum_def_id = tcx.parent(def_id);
1917 (enum_def_id, last - 1)
1918 } else {
1919 let generics = tcx.generics_of(def_id);
1925 (generics.parent.unwrap_or(def_id), last)
1928 };
1929 generic_segments.push(GenericPathSegment(generics_def_id, index));
1930 }
1931
1932 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
1934 generic_segments.push(GenericPathSegment(def_id, last));
1935 }
1936
1937 DefKind::AssocFn | DefKind::AssocConst => {
1939 if segments.len() >= 2 {
1940 let generics = tcx.generics_of(def_id);
1941 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
1942 }
1943 generic_segments.push(GenericPathSegment(def_id, last));
1944 }
1945
1946 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
1947 }
1948
1949 debug!(?generic_segments);
1950
1951 generic_segments
1952 }
1953
1954 #[instrument(level = "debug", skip_all)]
1956 pub fn lower_resolved_ty_path(
1957 &self,
1958 opt_self_ty: Option<Ty<'tcx>>,
1959 path: &hir::Path<'tcx>,
1960 hir_id: HirId,
1961 permit_variants: PermitVariants,
1962 ) -> Ty<'tcx> {
1963 debug!(?path.res, ?opt_self_ty, ?path.segments);
1964 let tcx = self.tcx();
1965
1966 let span = path.span;
1967 match path.res {
1968 Res::Def(DefKind::OpaqueTy, did) => {
1969 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
1971 let [leading_segments @ .., segment] = path.segments else { bug!() };
1972 let _ = self.prohibit_generic_args(
1973 leading_segments.iter(),
1974 GenericsArgsErrExtend::OpaqueTy,
1975 );
1976 let args = self.lower_generic_args_of_path_segment(span, did, segment);
1977 Ty::new_opaque(tcx, did, args)
1978 }
1979 Res::Def(
1980 DefKind::Enum
1981 | DefKind::TyAlias
1982 | DefKind::Struct
1983 | DefKind::Union
1984 | DefKind::ForeignTy,
1985 did,
1986 ) => {
1987 assert_eq!(opt_self_ty, None);
1988 let [leading_segments @ .., segment] = path.segments else { bug!() };
1989 let _ = self
1990 .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
1991 self.lower_path_segment(span, did, segment)
1992 }
1993 Res::Def(kind @ DefKind::Variant, def_id)
1994 if let PermitVariants::Yes = permit_variants =>
1995 {
1996 assert_eq!(opt_self_ty, None);
1999
2000 let generic_segments =
2001 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
2002 let indices: FxHashSet<_> =
2003 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
2004 let _ = self.prohibit_generic_args(
2005 path.segments.iter().enumerate().filter_map(|(index, seg)| {
2006 if !indices.contains(&index) { Some(seg) } else { None }
2007 }),
2008 GenericsArgsErrExtend::DefVariant(&path.segments),
2009 );
2010
2011 let &GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
2012 self.lower_path_segment(span, def_id, &path.segments[index])
2013 }
2014 Res::Def(DefKind::TyParam, def_id) => {
2015 assert_eq!(opt_self_ty, None);
2016 let _ = self.prohibit_generic_args(
2017 path.segments.iter(),
2018 GenericsArgsErrExtend::Param(def_id),
2019 );
2020 self.lower_ty_param(hir_id)
2021 }
2022 Res::SelfTyParam { .. } => {
2023 assert_eq!(opt_self_ty, None);
2025 let _ = self.prohibit_generic_args(
2026 path.segments.iter(),
2027 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2028 GenericsArgsErrExtend::SelfTyParam(
2029 ident.span.shrink_to_hi().to(args.span_ext),
2030 )
2031 } else {
2032 GenericsArgsErrExtend::None
2033 },
2034 );
2035 tcx.types.self_param
2036 }
2037 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
2038 assert_eq!(opt_self_ty, None);
2040 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
2042 let _ = self.prohibit_generic_args(
2043 path.segments.iter(),
2044 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
2045 );
2046 if forbid_generic && ty.has_param() {
2066 let mut err = self.dcx().struct_span_err(
2067 path.span,
2068 "generic `Self` types are currently not permitted in anonymous constants",
2069 );
2070 if let Some(hir::Node::Item(&hir::Item {
2071 kind: hir::ItemKind::Impl(impl_),
2072 ..
2073 })) = tcx.hir_get_if_local(def_id)
2074 {
2075 err.span_note(impl_.self_ty.span, "not a concrete type");
2076 }
2077 let reported = err.emit();
2078 Ty::new_error(tcx, reported)
2079 } else {
2080 ty
2081 }
2082 }
2083 Res::Def(DefKind::AssocTy, def_id) => {
2084 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2085 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2086 Some(trait_)
2087 } else {
2088 None
2089 };
2090 self.lower_resolved_assoc_ty_path(
2091 span,
2092 opt_self_ty,
2093 def_id,
2094 trait_segment,
2095 path.segments.last().unwrap(),
2096 )
2097 }
2098 Res::PrimTy(prim_ty) => {
2099 assert_eq!(opt_self_ty, None);
2100 let _ = self.prohibit_generic_args(
2101 path.segments.iter(),
2102 GenericsArgsErrExtend::PrimTy(prim_ty),
2103 );
2104 match prim_ty {
2105 hir::PrimTy::Bool => tcx.types.bool,
2106 hir::PrimTy::Char => tcx.types.char,
2107 hir::PrimTy::Int(it) => Ty::new_int(tcx, it),
2108 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, uit),
2109 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ft),
2110 hir::PrimTy::Str => tcx.types.str_,
2111 }
2112 }
2113 Res::Err => {
2114 let e = self
2115 .tcx()
2116 .dcx()
2117 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2118 Ty::new_error(tcx, e)
2119 }
2120 Res::Def(..) => {
2121 assert_eq!(
2122 path.segments.get(0).map(|seg| seg.ident.name),
2123 Some(kw::SelfUpper),
2124 "only expected incorrect resolution for `Self`"
2125 );
2126 Ty::new_error(
2127 self.tcx(),
2128 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2129 )
2130 }
2131 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2132 }
2133 }
2134
2135 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2140 let tcx = self.tcx();
2141 match tcx.named_bound_var(hir_id) {
2142 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2143 let br = ty::BoundTy {
2144 var: ty::BoundVar::from_u32(index),
2145 kind: ty::BoundTyKind::Param(def_id.to_def_id()),
2146 };
2147 Ty::new_bound(tcx, debruijn, br)
2148 }
2149 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2150 let item_def_id = tcx.hir_ty_param_owner(def_id);
2151 let generics = tcx.generics_of(item_def_id);
2152 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2153 Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2154 }
2155 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2156 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2157 }
2158 }
2159
2160 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2165 let tcx = self.tcx();
2166
2167 match tcx.named_bound_var(path_hir_id) {
2168 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2169 let item_def_id = tcx.parent(param_def_id);
2172 let generics = tcx.generics_of(item_def_id);
2173 let index = generics.param_def_id_to_index[¶m_def_id];
2174 let name = tcx.item_name(param_def_id);
2175 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2176 }
2177 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => ty::Const::new_bound(
2178 tcx,
2179 debruijn,
2180 ty::BoundConst { var: ty::BoundVar::from_u32(index) },
2181 ),
2182 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2183 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2184 }
2185 }
2186
2187 #[instrument(skip(self), level = "debug")]
2189 pub fn lower_const_arg(
2190 &self,
2191 const_arg: &hir::ConstArg<'tcx>,
2192 feed: FeedConstTy<'_, 'tcx>,
2193 ) -> Const<'tcx> {
2194 let tcx = self.tcx();
2195
2196 if let FeedConstTy::Param(param_def_id, args) = feed
2197 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2198 {
2199 let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2200
2201 if tcx.features().generic_const_parameter_types()
2210 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2211 {
2212 let e = self.dcx().span_err(
2213 const_arg.span(),
2214 "anonymous constants with lifetimes in their type are not yet supported",
2215 );
2216 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2217 return ty::Const::new_error(tcx, e);
2218 }
2219 if anon_const_type.has_non_region_infer() {
2223 let e = self.dcx().span_err(
2224 const_arg.span(),
2225 "anonymous constants with inferred types are not yet supported",
2226 );
2227 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2228 return ty::Const::new_error(tcx, e);
2229 }
2230 if anon_const_type.has_non_region_param() {
2233 let e = self.dcx().span_err(
2234 const_arg.span(),
2235 "anonymous constants referencing generics are not yet supported",
2236 );
2237 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2238 return ty::Const::new_error(tcx, e);
2239 }
2240
2241 tcx.feed_anon_const_type(
2242 anon.def_id,
2243 ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2244 );
2245 }
2246
2247 let hir_id = const_arg.hir_id;
2248 match const_arg.kind {
2249 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2250 debug!(?maybe_qself, ?path);
2251 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2252 self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2253 }
2254 hir::ConstArgKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2255 debug!(?hir_self_ty, ?segment);
2256 let self_ty = self.lower_ty(hir_self_ty);
2257 self.lower_type_relative_const_path(
2258 self_ty,
2259 hir_self_ty,
2260 segment,
2261 hir_id,
2262 const_arg.span(),
2263 )
2264 .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2265 }
2266 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2267 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2268 hir::ConstArgKind::Error(_, e) => ty::Const::new_error(tcx, e),
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 [leading_segments @ .., segment] = path.segments else { bug!() };
2293 let _ = self
2294 .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2295 let args = self.lower_generic_args_of_path_segment(span, did, segment);
2296 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2297 }
2298 Res::Def(DefKind::AssocConst, did) => {
2299 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2300 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2301 Some(trait_)
2302 } else {
2303 None
2304 };
2305 self.lower_resolved_assoc_const_path(
2306 span,
2307 opt_self_ty,
2308 did,
2309 trait_segment,
2310 path.segments.last().unwrap(),
2311 )
2312 }
2313 Res::Def(DefKind::Static { .. }, _) => {
2314 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2315 }
2316 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2318 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2319 let args = self.lower_generic_args_of_path_segment(
2320 span,
2321 did,
2322 path.segments.last().unwrap(),
2323 );
2324 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2325 }
2326
2327 res @ (Res::Def(
2330 DefKind::Mod
2331 | DefKind::Enum
2332 | DefKind::Variant
2333 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2334 | DefKind::Struct
2335 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2336 | DefKind::OpaqueTy
2337 | DefKind::TyAlias
2338 | DefKind::TraitAlias
2339 | DefKind::AssocTy
2340 | DefKind::Union
2341 | DefKind::Trait
2342 | DefKind::ForeignTy
2343 | DefKind::TyParam
2344 | DefKind::Macro(_)
2345 | DefKind::LifetimeParam
2346 | DefKind::Use
2347 | DefKind::ForeignMod
2348 | DefKind::AnonConst
2349 | DefKind::InlineConst
2350 | DefKind::Field
2351 | DefKind::Impl { .. }
2352 | DefKind::Closure
2353 | DefKind::ExternCrate
2354 | DefKind::GlobalAsm
2355 | DefKind::SyntheticCoroutineBody,
2356 _,
2357 )
2358 | Res::PrimTy(_)
2359 | Res::SelfTyParam { .. }
2360 | Res::SelfTyAlias { .. }
2361 | Res::SelfCtor(_)
2362 | Res::Local(_)
2363 | Res::ToolMod
2364 | Res::NonMacroAttr(_)
2365 | Res::Err) => Const::new_error_with_message(
2366 tcx,
2367 span,
2368 format!("invalid Res {res:?} for const path"),
2369 ),
2370 }
2371 }
2372
2373 #[instrument(skip(self), level = "debug")]
2375 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2376 let tcx = self.tcx();
2377
2378 let expr = &tcx.hir_body(anon.body).value;
2379 debug!(?expr);
2380
2381 let ty = tcx.type_of(anon.def_id).instantiate_identity();
2385
2386 match self.try_lower_anon_const_lit(ty, expr) {
2387 Some(v) => v,
2388 None => ty::Const::new_unevaluated(
2389 tcx,
2390 ty::UnevaluatedConst {
2391 def: anon.def_id.to_def_id(),
2392 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2393 },
2394 ),
2395 }
2396 }
2397
2398 #[instrument(skip(self), level = "debug")]
2399 fn try_lower_anon_const_lit(
2400 &self,
2401 ty: Ty<'tcx>,
2402 expr: &'tcx hir::Expr<'tcx>,
2403 ) -> Option<Const<'tcx>> {
2404 let tcx = self.tcx();
2405
2406 let expr = match &expr.kind {
2409 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2410 block.expr.as_ref().unwrap()
2411 }
2412 _ => expr,
2413 };
2414
2415 if let hir::ExprKind::Path(hir::QPath::Resolved(
2416 _,
2417 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2418 )) = expr.kind
2419 {
2420 span_bug!(
2421 expr.span,
2422 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2423 );
2424 };
2425
2426 let lit_input = match expr.kind {
2427 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: false }),
2428 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2429 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: true }),
2430 _ => None,
2431 },
2432 _ => None,
2433 };
2434
2435 lit_input
2436 .filter(|l| !l.ty.has_aliases())
2439 .map(|l| tcx.at(expr.span).lit_to_const(l))
2440 }
2441
2442 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2443 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2444 match idx {
2445 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2446 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2447 }
2448 }
2449
2450 #[instrument(level = "debug", skip(self), ret)]
2452 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2453 let tcx = self.tcx();
2454
2455 let result_ty = match &hir_ty.kind {
2456 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2457 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2458 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2459 hir::TyKind::Ref(region, mt) => {
2460 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2461 debug!(?r);
2462 let t = self.lower_ty(mt.ty);
2463 Ty::new_ref(tcx, r, t, mt.mutbl)
2464 }
2465 hir::TyKind::Never => tcx.types.never,
2466 hir::TyKind::Tup(fields) => {
2467 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2468 }
2469 hir::TyKind::FnPtr(bf) => {
2470 check_c_variadic_abi(tcx, bf.decl, bf.abi, hir_ty.span);
2471
2472 Ty::new_fn_ptr(
2473 tcx,
2474 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2475 )
2476 }
2477 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2478 tcx,
2479 ty::Binder::bind_with_vars(
2480 self.lower_ty(binder.inner_ty),
2481 tcx.late_bound_vars(hir_ty.hir_id),
2482 ),
2483 ),
2484 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2485 let lifetime = tagged_ptr.pointer();
2486 let syntax = tagged_ptr.tag();
2487 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, syntax)
2488 }
2489 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2493 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2494 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2495 }) =>
2496 {
2497 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2498 Ty::new_error(tcx, guar)
2499 }
2500 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2501 debug!(?maybe_qself, ?path);
2502 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2503 self.lower_resolved_ty_path(opt_self_ty, path, hir_ty.hir_id, PermitVariants::No)
2504 }
2505 &hir::TyKind::OpaqueDef(opaque_ty) => {
2506 let in_trait = match opaque_ty.origin {
2510 hir::OpaqueTyOrigin::FnReturn {
2511 parent,
2512 in_trait_or_impl: Some(hir::RpitContext::Trait),
2513 ..
2514 }
2515 | hir::OpaqueTyOrigin::AsyncFn {
2516 parent,
2517 in_trait_or_impl: Some(hir::RpitContext::Trait),
2518 ..
2519 } => Some(parent),
2520 hir::OpaqueTyOrigin::FnReturn {
2521 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2522 ..
2523 }
2524 | hir::OpaqueTyOrigin::AsyncFn {
2525 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2526 ..
2527 }
2528 | hir::OpaqueTyOrigin::TyAlias { .. } => None,
2529 };
2530
2531 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2532 }
2533 hir::TyKind::TraitAscription(hir_bounds) => {
2534 let self_ty = self.ty_infer(None, hir_ty.span);
2537 let mut bounds = Vec::new();
2538 self.lower_bounds(
2539 self_ty,
2540 hir_bounds.iter(),
2541 &mut bounds,
2542 ty::List::empty(),
2543 PredicateFilter::All,
2544 OverlappingAsssocItemConstraints::Allowed,
2545 );
2546 self.add_implicit_sizedness_bounds(
2547 &mut bounds,
2548 self_ty,
2549 hir_bounds,
2550 ImpliedBoundsContext::AssociatedTypeOrImplTrait,
2551 hir_ty.span,
2552 );
2553 self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2554 self_ty
2555 }
2556 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2560 if segment.args.is_some_and(|args| {
2561 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2562 }) =>
2563 {
2564 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2565 Ty::new_error(tcx, guar)
2566 }
2567 hir::TyKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2568 debug!(?hir_self_ty, ?segment);
2569 let self_ty = self.lower_ty(hir_self_ty);
2570 self.lower_type_relative_ty_path(
2571 self_ty,
2572 hir_self_ty,
2573 segment,
2574 hir_ty.hir_id,
2575 hir_ty.span,
2576 PermitVariants::No,
2577 )
2578 .map(|(ty, _, _)| ty)
2579 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2580 }
2581 hir::TyKind::Array(ty, length) => {
2582 let length = self.lower_const_arg(length, FeedConstTy::No);
2583 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2584 }
2585 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2586 hir::TyKind::Infer(()) => {
2587 self.ty_infer(None, hir_ty.span)
2592 }
2593 hir::TyKind::Pat(ty, pat) => {
2594 let ty_span = ty.span;
2595 let ty = self.lower_ty(ty);
2596 let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
2597 Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
2598 Err(guar) => Ty::new_error(tcx, guar),
2599 };
2600 self.record_ty(pat.hir_id, ty, pat.span);
2601 pat_ty
2602 }
2603 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2604 };
2605
2606 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2607 result_ty
2608 }
2609
2610 fn lower_pat_ty_pat(
2611 &self,
2612 ty: Ty<'tcx>,
2613 ty_span: Span,
2614 pat: &hir::TyPat<'tcx>,
2615 ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
2616 let tcx = self.tcx();
2617 match pat.kind {
2618 hir::TyPatKind::Range(start, end) => {
2619 match ty.kind() {
2620 ty::Int(_) | ty::Uint(_) | ty::Char => {
2623 let start = self.lower_const_arg(start, FeedConstTy::No);
2624 let end = self.lower_const_arg(end, FeedConstTy::No);
2625 Ok(ty::PatternKind::Range { start, end })
2626 }
2627 _ => Err(self
2628 .dcx()
2629 .span_delayed_bug(ty_span, "invalid base type for range pattern")),
2630 }
2631 }
2632 hir::TyPatKind::NotNull => Ok(ty::PatternKind::NotNull),
2633 hir::TyPatKind::Or(patterns) => {
2634 self.tcx()
2635 .mk_patterns_from_iter(patterns.iter().map(|pat| {
2636 self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
2637 }))
2638 .map(ty::PatternKind::Or)
2639 }
2640 hir::TyPatKind::Err(e) => Err(e),
2641 }
2642 }
2643
2644 #[instrument(level = "debug", skip(self), ret)]
2646 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: Option<LocalDefId>) -> Ty<'tcx> {
2647 let tcx = self.tcx();
2648
2649 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2650 debug!(?lifetimes);
2651
2652 let def_id = if let Some(parent_def_id) = in_trait {
2656 *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
2657 .iter()
2658 .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
2659 Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
2660 opaque_def_id.expect_local() == def_id
2661 }
2662 _ => unreachable!(),
2663 })
2664 .unwrap()
2665 } else {
2666 def_id.to_def_id()
2667 };
2668
2669 let generics = tcx.generics_of(def_id);
2670 debug!(?generics);
2671
2672 let offset = generics.count() - lifetimes.len();
2676
2677 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2678 if let Some(i) = (param.index as usize).checked_sub(offset) {
2679 let (lifetime, _) = lifetimes[i];
2680 self.lower_resolved_lifetime(lifetime).into()
2681 } else {
2682 tcx.mk_param_from_def(param)
2683 }
2684 });
2685 debug!(?args);
2686
2687 if in_trait.is_some() {
2688 Ty::new_projection_from_args(tcx, def_id, args)
2689 } else {
2690 Ty::new_opaque(tcx, def_id, args)
2691 }
2692 }
2693
2694 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2696 pub fn lower_fn_ty(
2697 &self,
2698 hir_id: HirId,
2699 safety: hir::Safety,
2700 abi: rustc_abi::ExternAbi,
2701 decl: &hir::FnDecl<'tcx>,
2702 generics: Option<&hir::Generics<'_>>,
2703 hir_ty: Option<&hir::Ty<'_>>,
2704 ) -> ty::PolyFnSig<'tcx> {
2705 let tcx = self.tcx();
2706 let bound_vars = tcx.late_bound_vars(hir_id);
2707 debug!(?bound_vars);
2708
2709 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2710
2711 debug!(?output_ty);
2712
2713 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2714 let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2715
2716 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), span, .. }) =
2717 tcx.hir_node(hir_id)
2718 {
2719 check_abi(tcx, hir_id, *span, fn_ptr_ty.abi);
2720 }
2721
2722 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, fn_ptr_ty);
2724
2725 if !fn_ptr_ty.references_error() {
2726 let inputs = fn_ptr_ty.inputs();
2733 let late_bound_in_args =
2734 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2735 let output = fn_ptr_ty.output();
2736 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2737
2738 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2739 struct_span_code_err!(
2740 self.dcx(),
2741 decl.output.span(),
2742 E0581,
2743 "return type references {}, which is not constrained by the fn input types",
2744 br_name
2745 )
2746 });
2747 }
2748
2749 fn_ptr_ty
2750 }
2751
2752 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2757 &self,
2758 fn_hir_id: HirId,
2759 arg_idx: Option<usize>,
2760 ) -> Option<Ty<'tcx>> {
2761 let tcx = self.tcx();
2762 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2763 tcx.hir_node(fn_hir_id)
2764 else {
2765 return None;
2766 };
2767 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2768
2769 let trait_ref = self.lower_impl_trait_ref(&i.of_trait?.trait_ref, self.lower_ty(i.self_ty));
2770
2771 let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
2772 tcx,
2773 *ident,
2774 ty::AssocTag::Fn,
2775 trait_ref.def_id,
2776 )?;
2777
2778 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2779 tcx,
2780 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2781 );
2782 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2783
2784 Some(if let Some(arg_idx) = arg_idx {
2785 *fn_sig.inputs().get(arg_idx)?
2786 } else {
2787 fn_sig.output()
2788 })
2789 }
2790
2791 #[instrument(level = "trace", skip(self, generate_err))]
2792 fn validate_late_bound_regions<'cx>(
2793 &'cx self,
2794 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2795 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2796 generate_err: impl Fn(&str) -> Diag<'cx>,
2797 ) {
2798 for br in referenced_regions.difference(&constrained_regions) {
2799 let br_name = if let Some(name) = br.get_name(self.tcx()) {
2800 format!("lifetime `{name}`")
2801 } else {
2802 "an anonymous lifetime".to_string()
2803 };
2804
2805 let mut err = generate_err(&br_name);
2806
2807 if !br.is_named(self.tcx()) {
2808 err.note(
2815 "lifetimes appearing in an associated or opaque type are not considered constrained",
2816 );
2817 err.note("consider introducing a named lifetime parameter");
2818 }
2819
2820 err.emit();
2821 }
2822 }
2823
2824 #[instrument(level = "debug", skip(self, span), ret)]
2832 fn compute_object_lifetime_bound(
2833 &self,
2834 span: Span,
2835 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2836 ) -> Option<ty::Region<'tcx>> {
2838 let tcx = self.tcx();
2839
2840 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2843
2844 if derived_region_bounds.is_empty() {
2847 return None;
2848 }
2849
2850 if derived_region_bounds.iter().any(|r| r.is_static()) {
2853 return Some(tcx.lifetimes.re_static);
2854 }
2855
2856 let r = derived_region_bounds[0];
2860 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2861 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2862 }
2863 Some(r)
2864 }
2865}