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