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(Debug)]
61pub struct GenericPathSegment(pub DefId, pub usize);
62
63#[derive(Copy, Clone, Debug)]
64pub enum PredicateFilter {
65 All,
67
68 SelfOnly,
70
71 SelfTraitThatDefines(Ident),
75
76 SelfAndAssociatedTypeBounds,
80
81 ConstIfConst,
83
84 SelfConstIfConst,
86}
87
88#[derive(Debug)]
89pub enum RegionInferReason<'a> {
90 ExplicitObjectLifetime,
92 ObjectLifetimeDefault,
94 Param(&'a ty::GenericParamDef),
96 RegionPredicate,
97 Reference,
98 OutlivesBound,
99}
100
101#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Debug)]
102pub struct InherentAssocCandidate {
103 pub impl_: DefId,
104 pub assoc_item: DefId,
105 pub scope: DefId,
106}
107
108pub trait HirTyLowerer<'tcx> {
113 fn tcx(&self) -> TyCtxt<'tcx>;
114
115 fn dcx(&self) -> DiagCtxtHandle<'_>;
116
117 fn item_def_id(&self) -> LocalDefId;
119
120 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
122
123 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
125
126 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
128
129 fn register_trait_ascription_bounds(
130 &self,
131 bounds: Vec<(ty::Clause<'tcx>, Span)>,
132 hir_id: HirId,
133 span: Span,
134 );
135
136 fn probe_ty_param_bounds(
151 &self,
152 span: Span,
153 def_id: LocalDefId,
154 assoc_ident: Ident,
155 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
156
157 fn select_inherent_assoc_candidates(
158 &self,
159 span: Span,
160 self_ty: Ty<'tcx>,
161 candidates: Vec<InherentAssocCandidate>,
162 ) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>);
163
164 fn lower_assoc_item_path(
177 &self,
178 span: Span,
179 item_def_id: DefId,
180 item_segment: &hir::PathSegment<'tcx>,
181 poly_trait_ref: ty::PolyTraitRef<'tcx>,
182 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
183
184 fn lower_fn_sig(
185 &self,
186 decl: &hir::FnDecl<'tcx>,
187 generics: Option<&hir::Generics<'_>>,
188 hir_id: HirId,
189 hir_ty: Option<&hir::Ty<'_>>,
190 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
191
192 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
199
200 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
202
203 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
205
206 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
211 where
212 Self: Sized,
213 {
214 self
215 }
216
217 fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation>;
220}
221
222enum AssocItemQSelf {
226 Trait(DefId),
227 TyParam(LocalDefId, Span),
228 SelfTyAlias,
229}
230
231impl AssocItemQSelf {
232 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
233 match *self {
234 Self::Trait(def_id) => tcx.def_path_str(def_id),
235 Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
236 Self::SelfTyAlias => kw::SelfUpper.to_string(),
237 }
238 }
239}
240
241#[derive(Debug, Clone, Copy)]
248pub enum FeedConstTy<'a, 'tcx> {
249 Param(DefId, &'a [ty::GenericArg<'tcx>]),
257 No,
259}
260
261#[derive(Debug, Clone, Copy)]
262enum LowerTypeRelativePathMode {
263 Type(PermitVariants),
264 Const,
265}
266
267impl LowerTypeRelativePathMode {
268 fn assoc_tag(self) -> ty::AssocTag {
269 match self {
270 Self::Type(_) => ty::AssocTag::Type,
271 Self::Const => ty::AssocTag::Const,
272 }
273 }
274
275 fn def_kind(self) -> DefKind {
276 match self {
277 Self::Type(_) => DefKind::AssocTy,
278 Self::Const => DefKind::AssocConst,
279 }
280 }
281
282 fn permit_variants(self) -> PermitVariants {
283 match self {
284 Self::Type(permit_variants) => permit_variants,
285 Self::Const => PermitVariants::No,
288 }
289 }
290}
291
292#[derive(Debug, Clone, Copy)]
294pub enum PermitVariants {
295 Yes,
296 No,
297}
298
299#[derive(Debug, Clone, Copy)]
300enum TypeRelativePath<'tcx> {
301 AssocItem(DefId, GenericArgsRef<'tcx>),
302 Variant { adt: Ty<'tcx>, variant_did: DefId },
303}
304
305#[derive(Copy, Clone, PartialEq, Debug)]
315pub enum ExplicitLateBound {
316 Yes,
317 No,
318}
319
320#[derive(Copy, Clone, PartialEq)]
321pub enum IsMethodCall {
322 Yes,
323 No,
324}
325
326#[derive(Copy, Clone, PartialEq)]
329pub(crate) enum GenericArgPosition {
330 Type,
331 Value, MethodCall,
333}
334
335#[derive(Clone, Debug)]
338pub struct GenericArgCountMismatch {
339 pub reported: ErrorGuaranteed,
340 pub invalid_args: Vec<usize>,
342}
343
344#[derive(Clone, Debug)]
347pub struct GenericArgCountResult {
348 pub explicit_late_bound: ExplicitLateBound,
349 pub correct: Result<(), GenericArgCountMismatch>,
350}
351
352pub trait GenericArgsLowerer<'a, 'tcx> {
357 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
358
359 fn provided_kind(
360 &mut self,
361 preceding_args: &[ty::GenericArg<'tcx>],
362 param: &ty::GenericParamDef,
363 arg: &GenericArg<'tcx>,
364 ) -> ty::GenericArg<'tcx>;
365
366 fn inferred_kind(
367 &mut self,
368 preceding_args: &[ty::GenericArg<'tcx>],
369 param: &ty::GenericParamDef,
370 infer_args: bool,
371 ) -> ty::GenericArg<'tcx>;
372}
373
374impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
375 #[instrument(level = "debug", skip(self), ret)]
377 pub fn lower_lifetime(
378 &self,
379 lifetime: &hir::Lifetime,
380 reason: RegionInferReason<'_>,
381 ) -> ty::Region<'tcx> {
382 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
383 self.lower_resolved_lifetime(resolved)
384 } else {
385 self.re_infer(lifetime.ident.span, reason)
386 }
387 }
388
389 #[instrument(level = "debug", skip(self), ret)]
391 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
392 let tcx = self.tcx();
393
394 match resolved {
395 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
396
397 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
398 let br = ty::BoundRegion {
399 var: ty::BoundVar::from_u32(index),
400 kind: ty::BoundRegionKind::Named(def_id.to_def_id()),
401 };
402 ty::Region::new_bound(tcx, debruijn, br)
403 }
404
405 rbv::ResolvedArg::EarlyBound(def_id) => {
406 let name = tcx.hir_ty_param_name(def_id);
407 let item_def_id = tcx.hir_ty_param_owner(def_id);
408 let generics = tcx.generics_of(item_def_id);
409 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
410 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
411 }
412
413 rbv::ResolvedArg::Free(scope, id) => {
414 ty::Region::new_late_param(
415 tcx,
416 scope.to_def_id(),
417 ty::LateParamRegionKind::Named(id.to_def_id()),
418 )
419
420 }
422
423 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
424 }
425 }
426
427 pub fn lower_generic_args_of_path_segment(
428 &self,
429 span: Span,
430 def_id: DefId,
431 item_segment: &hir::PathSegment<'tcx>,
432 ) -> GenericArgsRef<'tcx> {
433 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
434 if let Some(c) = item_segment.args().constraints.first() {
435 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
436 }
437 args
438 }
439
440 #[instrument(level = "debug", skip(self, span), ret)]
475 fn lower_generic_args_of_path(
476 &self,
477 span: Span,
478 def_id: DefId,
479 parent_args: &[ty::GenericArg<'tcx>],
480 segment: &hir::PathSegment<'tcx>,
481 self_ty: Option<Ty<'tcx>>,
482 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
483 let tcx = self.tcx();
488 let generics = tcx.generics_of(def_id);
489 debug!(?generics);
490
491 if generics.has_self {
492 if generics.parent.is_some() {
493 assert!(!parent_args.is_empty())
496 } else {
497 assert!(self_ty.is_some());
499 }
500 } else {
501 assert!(self_ty.is_none());
502 }
503
504 let arg_count = check_generic_arg_count(
505 self,
506 def_id,
507 segment,
508 generics,
509 GenericArgPosition::Type,
510 self_ty.is_some(),
511 );
512
513 if generics.is_own_empty() {
518 return (tcx.mk_args(parent_args), arg_count);
519 }
520
521 struct GenericArgsCtxt<'a, 'tcx> {
522 lowerer: &'a dyn HirTyLowerer<'tcx>,
523 def_id: DefId,
524 generic_args: &'a GenericArgs<'tcx>,
525 span: Span,
526 infer_args: bool,
527 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
528 }
529
530 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
531 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
532 if did == self.def_id {
533 (Some(self.generic_args), self.infer_args)
534 } else {
535 (None, false)
537 }
538 }
539
540 fn provided_kind(
541 &mut self,
542 preceding_args: &[ty::GenericArg<'tcx>],
543 param: &ty::GenericParamDef,
544 arg: &GenericArg<'tcx>,
545 ) -> ty::GenericArg<'tcx> {
546 let tcx = self.lowerer.tcx();
547
548 if let Err(incorrect) = self.incorrect_args {
549 if incorrect.invalid_args.contains(&(param.index as usize)) {
550 return param.to_error(tcx);
551 }
552 }
553
554 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
555 if has_default {
556 tcx.check_optional_stability(
557 param.def_id,
558 Some(arg.hir_id()),
559 arg.span(),
560 None,
561 AllowUnstable::No,
562 |_, _| {
563 },
569 );
570 }
571 self.lowerer.lower_ty(ty).into()
572 };
573
574 match (¶m.kind, arg) {
575 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
576 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
577 }
578 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
579 handle_ty_args(has_default, ty.as_unambig_ty())
581 }
582 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
583 handle_ty_args(has_default, &inf.to_ty())
584 }
585 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
586 .lowerer
587 .lower_const_arg(
589 ct.as_unambig_ct(),
590 FeedConstTy::Param(param.def_id, preceding_args),
591 )
592 .into(),
593 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
594 self.lowerer.ct_infer(Some(param), inf.span).into()
595 }
596 (kind, arg) => span_bug!(
597 self.span,
598 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
599 ),
600 }
601 }
602
603 fn inferred_kind(
604 &mut self,
605 preceding_args: &[ty::GenericArg<'tcx>],
606 param: &ty::GenericParamDef,
607 infer_args: bool,
608 ) -> ty::GenericArg<'tcx> {
609 let tcx = self.lowerer.tcx();
610
611 if let Err(incorrect) = self.incorrect_args {
612 if incorrect.invalid_args.contains(&(param.index as usize)) {
613 return param.to_error(tcx);
614 }
615 }
616 match param.kind {
617 GenericParamDefKind::Lifetime => {
618 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
619 }
620 GenericParamDefKind::Type { has_default, .. } => {
621 if !infer_args && has_default {
622 if let Some(prev) =
624 preceding_args.iter().find_map(|arg| match arg.kind() {
625 GenericArgKind::Type(ty) => ty.error_reported().err(),
626 _ => None,
627 })
628 {
629 return Ty::new_error(tcx, prev).into();
631 }
632 tcx.at(self.span)
633 .type_of(param.def_id)
634 .instantiate(tcx, preceding_args)
635 .into()
636 } else if infer_args {
637 self.lowerer.ty_infer(Some(param), self.span).into()
638 } else {
639 Ty::new_misc_error(tcx).into()
641 }
642 }
643 GenericParamDefKind::Const { has_default, .. } => {
644 let ty = tcx
645 .at(self.span)
646 .type_of(param.def_id)
647 .instantiate(tcx, preceding_args);
648 if let Err(guar) = ty.error_reported() {
649 return ty::Const::new_error(tcx, guar).into();
650 }
651 if !infer_args && has_default {
652 tcx.const_param_default(param.def_id)
653 .instantiate(tcx, preceding_args)
654 .into()
655 } else if infer_args {
656 self.lowerer.ct_infer(Some(param), self.span).into()
657 } else {
658 ty::Const::new_misc_error(tcx).into()
660 }
661 }
662 }
663 }
664 }
665
666 let mut args_ctx = GenericArgsCtxt {
667 lowerer: self,
668 def_id,
669 span,
670 generic_args: segment.args(),
671 infer_args: segment.infer_args,
672 incorrect_args: &arg_count.correct,
673 };
674 let args = lower_generic_args(
675 self,
676 def_id,
677 parent_args,
678 self_ty.is_some(),
679 self_ty,
680 &arg_count,
681 &mut args_ctx,
682 );
683
684 (args, arg_count)
685 }
686
687 #[instrument(level = "debug", skip(self))]
688 pub fn lower_generic_args_of_assoc_item(
689 &self,
690 span: Span,
691 item_def_id: DefId,
692 item_segment: &hir::PathSegment<'tcx>,
693 parent_args: GenericArgsRef<'tcx>,
694 ) -> GenericArgsRef<'tcx> {
695 let (args, _) =
696 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
697 if let Some(c) = item_segment.args().constraints.first() {
698 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
699 }
700 args
701 }
702
703 pub fn lower_impl_trait_ref(
707 &self,
708 trait_ref: &hir::TraitRef<'tcx>,
709 self_ty: Ty<'tcx>,
710 ) -> ty::TraitRef<'tcx> {
711 let _ = self.prohibit_generic_args(
712 trait_ref.path.segments.split_last().unwrap().1.iter(),
713 GenericsArgsErrExtend::None,
714 );
715
716 self.lower_mono_trait_ref(
717 trait_ref.path.span,
718 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
719 self_ty,
720 trait_ref.path.segments.last().unwrap(),
721 true,
722 )
723 }
724
725 #[instrument(level = "debug", skip(self, bounds))]
749 pub(crate) fn lower_poly_trait_ref(
750 &self,
751 poly_trait_ref: &hir::PolyTraitRef<'tcx>,
752 self_ty: Ty<'tcx>,
753 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
754 predicate_filter: PredicateFilter,
755 ) -> GenericArgCountResult {
756 let tcx = self.tcx();
757
758 let hir::PolyTraitRef { bound_generic_params: _, modifiers, ref trait_ref, span } =
761 *poly_trait_ref;
762 let hir::TraitBoundModifiers { constness, polarity } = modifiers;
763
764 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
765
766 let (polarity, bounds) = match polarity {
771 rustc_ast::BoundPolarity::Positive
772 if tcx.is_lang_item(trait_def_id, hir::LangItem::PointeeSized) =>
773 {
774 (ty::PredicatePolarity::Positive, &mut Vec::new())
780 }
781 rustc_ast::BoundPolarity::Positive => (ty::PredicatePolarity::Positive, bounds),
782 rustc_ast::BoundPolarity::Negative(_) => (ty::PredicatePolarity::Negative, bounds),
783 rustc_ast::BoundPolarity::Maybe(_) => {
784 (ty::PredicatePolarity::Positive, &mut Vec::new())
785 }
786 };
787
788 let trait_segment = trait_ref.path.segments.last().unwrap();
789
790 let _ = self.prohibit_generic_args(
791 trait_ref.path.segments.split_last().unwrap().1.iter(),
792 GenericsArgsErrExtend::None,
793 );
794 self.report_internal_fn_trait(span, trait_def_id, trait_segment, false);
795
796 let (generic_args, arg_count) = self.lower_generic_args_of_path(
797 trait_ref.path.span,
798 trait_def_id,
799 &[],
800 trait_segment,
801 Some(self_ty),
802 );
803
804 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
805 debug!(?bound_vars);
806
807 let poly_trait_ref = ty::Binder::bind_with_vars(
808 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
809 bound_vars,
810 );
811
812 debug!(?poly_trait_ref);
813
814 match predicate_filter {
816 PredicateFilter::All
817 | PredicateFilter::SelfOnly
818 | PredicateFilter::SelfTraitThatDefines(..)
819 | PredicateFilter::SelfAndAssociatedTypeBounds => {
820 let bound = poly_trait_ref.map_bound(|trait_ref| {
821 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
822 });
823 let bound = (bound.upcast(tcx), span);
824 if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
830 bounds.insert(0, bound);
831 } else {
832 bounds.push(bound);
833 }
834 }
835 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
836 }
837
838 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
839 && !self.tcx().is_const_trait(trait_def_id)
840 {
841 let (def_span, suggestion, suggestion_pre) =
842 match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) {
843 (true, true) => (
844 None,
845 Some(tcx.def_span(trait_def_id).shrink_to_lo()),
846 if self.tcx().features().const_trait_impl() {
847 ""
848 } else {
849 "enable `#![feature(const_trait_impl)]` in your crate and "
850 },
851 ),
852 (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
853 };
854 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
855 span,
856 modifier: constness.as_str(),
857 def_span,
858 trait_name: self.tcx().def_path_str(trait_def_id),
859 suggestion_pre,
860 suggestion,
861 });
862 } else {
863 match predicate_filter {
864 PredicateFilter::SelfTraitThatDefines(..) => {}
866 PredicateFilter::All
867 | PredicateFilter::SelfOnly
868 | PredicateFilter::SelfAndAssociatedTypeBounds => {
869 match constness {
870 hir::BoundConstness::Always(_) => {
871 if polarity == ty::PredicatePolarity::Positive {
872 bounds.push((
873 poly_trait_ref
874 .to_host_effect_clause(tcx, ty::BoundConstness::Const),
875 span,
876 ));
877 }
878 }
879 hir::BoundConstness::Maybe(_) => {
880 }
885 hir::BoundConstness::Never => {}
886 }
887 }
888 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
895 match constness {
896 hir::BoundConstness::Maybe(_) => {
897 if polarity == ty::PredicatePolarity::Positive {
898 bounds.push((
899 poly_trait_ref
900 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
901 span,
902 ));
903 }
904 }
905 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
906 }
907 }
908 }
909 }
910
911 let mut dup_constraints = FxIndexMap::default();
912 for constraint in trait_segment.args().constraints {
913 if polarity == ty::PredicatePolarity::Negative {
917 self.dcx().span_delayed_bug(
918 constraint.span,
919 "negative trait bounds should not have assoc item constraints",
920 );
921 break;
922 }
923
924 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
926 trait_ref.hir_ref_id,
927 poly_trait_ref,
928 constraint,
929 bounds,
930 &mut dup_constraints,
931 constraint.span,
932 predicate_filter,
933 );
934 }
936
937 arg_count
938 }
939
940 fn lower_mono_trait_ref(
944 &self,
945 span: Span,
946 trait_def_id: DefId,
947 self_ty: Ty<'tcx>,
948 trait_segment: &hir::PathSegment<'tcx>,
949 is_impl: bool,
950 ) -> ty::TraitRef<'tcx> {
951 self.report_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
952
953 let (generic_args, _) =
954 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
955 if let Some(c) = trait_segment.args().constraints.first() {
956 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
957 }
958 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
959 }
960
961 fn probe_trait_that_defines_assoc_item(
962 &self,
963 trait_def_id: DefId,
964 assoc_tag: ty::AssocTag,
965 assoc_ident: Ident,
966 ) -> bool {
967 self.tcx()
968 .associated_items(trait_def_id)
969 .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
970 .is_some()
971 }
972
973 fn lower_path_segment(
974 &self,
975 span: Span,
976 did: DefId,
977 item_segment: &hir::PathSegment<'tcx>,
978 ) -> Ty<'tcx> {
979 let tcx = self.tcx();
980 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
981
982 if let DefKind::TyAlias = tcx.def_kind(did)
983 && tcx.type_alias_is_lazy(did)
984 {
985 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
989 Ty::new_alias(tcx, ty::Free, alias_ty)
990 } else {
991 tcx.at(span).type_of(did).instantiate(tcx, args)
992 }
993 }
994
995 #[instrument(level = "debug", skip_all, ret)]
1003 fn probe_single_ty_param_bound_for_assoc_item(
1004 &self,
1005 ty_param_def_id: LocalDefId,
1006 ty_param_span: Span,
1007 assoc_tag: ty::AssocTag,
1008 assoc_ident: Ident,
1009 span: Span,
1010 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
1011 debug!(?ty_param_def_id, ?assoc_ident, ?span);
1012 let tcx = self.tcx();
1013
1014 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
1015 debug!("predicates={:#?}", predicates);
1016
1017 self.probe_single_bound_for_assoc_item(
1018 || {
1019 let trait_refs = predicates
1020 .iter_identity_copied()
1021 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
1022 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
1023 },
1024 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
1025 assoc_tag,
1026 assoc_ident,
1027 span,
1028 None,
1029 )
1030 }
1031
1032 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1038 fn probe_single_bound_for_assoc_item<I>(
1039 &self,
1040 all_candidates: impl Fn() -> I,
1041 qself: AssocItemQSelf,
1042 assoc_tag: ty::AssocTag,
1043 assoc_ident: Ident,
1044 span: Span,
1045 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1046 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1047 where
1048 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1049 {
1050 let tcx = self.tcx();
1051
1052 let mut matching_candidates = all_candidates().filter(|r| {
1053 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
1054 });
1055
1056 let Some(bound) = matching_candidates.next() else {
1057 return Err(self.report_unresolved_assoc_item(
1058 all_candidates,
1059 qself,
1060 assoc_tag,
1061 assoc_ident,
1062 span,
1063 constraint,
1064 ));
1065 };
1066 debug!(?bound);
1067
1068 if let Some(bound2) = matching_candidates.next() {
1069 debug!(?bound2);
1070
1071 let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
1072 let qself_str = qself.to_string(tcx);
1073 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1074 span,
1075 assoc_kind: assoc_kind_str,
1076 assoc_ident,
1077 qself: &qself_str,
1078 });
1079 err.code(
1081 if let Some(constraint) = constraint
1082 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1083 {
1084 E0222
1085 } else {
1086 E0221
1087 },
1088 );
1089
1090 let mut where_bounds = vec![];
1094 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1095 let bound_id = bound.def_id();
1096 let bound_span = tcx
1097 .associated_items(bound_id)
1098 .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1099 .and_then(|item| tcx.hir_span_if_local(item.def_id));
1100
1101 if let Some(bound_span) = bound_span {
1102 err.span_label(
1103 bound_span,
1104 format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
1105 );
1106 if let Some(constraint) = constraint {
1107 match constraint.kind {
1108 hir::AssocItemConstraintKind::Equality { term } => {
1109 let term: ty::Term<'_> = match term {
1110 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1111 hir::Term::Const(ct) => {
1112 self.lower_const_arg(ct, FeedConstTy::No).into()
1113 }
1114 };
1115 if term.references_error() {
1116 continue;
1117 }
1118 where_bounds.push(format!(
1120 " T: {trait}::{assoc_ident} = {term}",
1121 trait = bound.print_only_trait_path(),
1122 ));
1123 }
1124 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1126 }
1127 } else {
1128 err.span_suggestion_verbose(
1129 span.with_hi(assoc_ident.span.lo()),
1130 "use fully-qualified syntax to disambiguate",
1131 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1132 Applicability::MaybeIncorrect,
1133 );
1134 }
1135 } else {
1136 let trait_ =
1137 tcx.short_string(bound.print_only_trait_path(), err.long_ty_path());
1138 err.note(format!(
1139 "associated {assoc_kind_str} `{assoc_ident}` could derive from `{trait_}`",
1140 ));
1141 }
1142 }
1143 if !where_bounds.is_empty() {
1144 err.help(format!(
1145 "consider introducing a new type parameter `T` and adding `where` constraints:\
1146 \n where\n T: {qself_str},\n{}",
1147 where_bounds.join(",\n"),
1148 ));
1149 let reported = err.emit();
1150 return Err(reported);
1151 }
1152 err.emit();
1153 }
1154
1155 Ok(bound)
1156 }
1157
1158 #[instrument(level = "debug", skip_all, ret)]
1185 pub fn lower_type_relative_ty_path(
1186 &self,
1187 self_ty: Ty<'tcx>,
1188 hir_self_ty: &'tcx hir::Ty<'tcx>,
1189 segment: &'tcx hir::PathSegment<'tcx>,
1190 qpath_hir_id: HirId,
1191 span: Span,
1192 permit_variants: PermitVariants,
1193 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1194 let tcx = self.tcx();
1195 match self.lower_type_relative_path(
1196 self_ty,
1197 hir_self_ty,
1198 segment,
1199 qpath_hir_id,
1200 span,
1201 LowerTypeRelativePathMode::Type(permit_variants),
1202 )? {
1203 TypeRelativePath::AssocItem(def_id, args) => {
1204 let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1205 let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1206 Ok((ty, tcx.def_kind(def_id), def_id))
1207 }
1208 TypeRelativePath::Variant { adt, variant_did } => {
1209 Ok((adt, DefKind::Variant, variant_did))
1210 }
1211 }
1212 }
1213
1214 #[instrument(level = "debug", skip_all, ret)]
1216 fn lower_type_relative_const_path(
1217 &self,
1218 self_ty: Ty<'tcx>,
1219 hir_self_ty: &'tcx hir::Ty<'tcx>,
1220 segment: &'tcx hir::PathSegment<'tcx>,
1221 qpath_hir_id: HirId,
1222 span: Span,
1223 ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1224 let tcx = self.tcx();
1225 let (def_id, args) = match self.lower_type_relative_path(
1226 self_ty,
1227 hir_self_ty,
1228 segment,
1229 qpath_hir_id,
1230 span,
1231 LowerTypeRelativePathMode::Const,
1232 )? {
1233 TypeRelativePath::AssocItem(def_id, args) => {
1234 if !tcx.associated_item(def_id).is_type_const_capable(tcx) {
1235 let mut err = self.dcx().struct_span_err(
1236 span,
1237 "use of trait associated const without `#[type_const]`",
1238 );
1239 err.note("the declaration in the trait must be marked with `#[type_const]`");
1240 return Err(err.emit());
1241 }
1242 (def_id, args)
1243 }
1244 TypeRelativePath::Variant { .. } => {
1247 span_bug!(span, "unexpected variant res for type associated const path")
1248 }
1249 };
1250 Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
1251 }
1252
1253 #[instrument(level = "debug", skip_all, ret)]
1255 fn lower_type_relative_path(
1256 &self,
1257 self_ty: Ty<'tcx>,
1258 hir_self_ty: &'tcx hir::Ty<'tcx>,
1259 segment: &'tcx hir::PathSegment<'tcx>,
1260 qpath_hir_id: HirId,
1261 span: Span,
1262 mode: LowerTypeRelativePathMode,
1263 ) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
1264 debug!(%self_ty, ?segment.ident);
1265 let tcx = self.tcx();
1266
1267 let mut variant_def_id = None;
1269 if let Some(adt_def) = self.probe_adt(span, self_ty) {
1270 if adt_def.is_enum() {
1271 let variant_def = adt_def
1272 .variants()
1273 .iter()
1274 .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
1275 if let Some(variant_def) = variant_def {
1276 if let PermitVariants::Yes = mode.permit_variants() {
1277 tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1278 let _ = self.prohibit_generic_args(
1279 slice::from_ref(segment).iter(),
1280 GenericsArgsErrExtend::EnumVariant {
1281 qself: hir_self_ty,
1282 assoc_segment: segment,
1283 adt_def,
1284 },
1285 );
1286 return Ok(TypeRelativePath::Variant {
1287 adt: self_ty,
1288 variant_did: variant_def.def_id,
1289 });
1290 } else {
1291 variant_def_id = Some(variant_def.def_id);
1292 }
1293 }
1294 }
1295
1296 if let Some((did, args)) = self.probe_inherent_assoc_item(
1298 segment,
1299 adt_def.did(),
1300 self_ty,
1301 qpath_hir_id,
1302 span,
1303 mode.assoc_tag(),
1304 )? {
1305 return Ok(TypeRelativePath::AssocItem(did, args));
1306 }
1307 }
1308
1309 let (item_def_id, bound) = self.resolve_type_relative_path(
1310 self_ty,
1311 hir_self_ty,
1312 mode.assoc_tag(),
1313 segment,
1314 qpath_hir_id,
1315 span,
1316 variant_def_id,
1317 )?;
1318
1319 let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
1320
1321 if let Some(variant_def_id) = variant_def_id {
1322 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
1323 lint.primary_message("ambiguous associated item");
1324 let mut could_refer_to = |kind: DefKind, def_id, also| {
1325 let note_msg = format!(
1326 "`{}` could{} refer to the {} defined here",
1327 segment.ident,
1328 also,
1329 tcx.def_kind_descr(kind, def_id)
1330 );
1331 lint.span_note(tcx.def_span(def_id), note_msg);
1332 };
1333
1334 could_refer_to(DefKind::Variant, variant_def_id, "");
1335 could_refer_to(mode.def_kind(), item_def_id, " also");
1336
1337 lint.span_suggestion(
1338 span,
1339 "use fully-qualified syntax",
1340 format!(
1341 "<{} as {}>::{}",
1342 self_ty,
1343 tcx.item_name(bound.def_id()),
1344 segment.ident
1345 ),
1346 Applicability::MachineApplicable,
1347 );
1348 });
1349 }
1350
1351 Ok(TypeRelativePath::AssocItem(item_def_id, args))
1352 }
1353
1354 fn resolve_type_relative_path(
1356 &self,
1357 self_ty: Ty<'tcx>,
1358 hir_self_ty: &'tcx hir::Ty<'tcx>,
1359 assoc_tag: ty::AssocTag,
1360 segment: &'tcx hir::PathSegment<'tcx>,
1361 qpath_hir_id: HirId,
1362 span: Span,
1363 variant_def_id: Option<DefId>,
1364 ) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
1365 let tcx = self.tcx();
1366
1367 let self_ty_res = match hir_self_ty.kind {
1368 hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
1369 _ => Res::Err,
1370 };
1371
1372 let bound = match (self_ty.kind(), self_ty_res) {
1374 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1375 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1378 self.dcx().span_bug(span, "expected cycle error");
1380 };
1381
1382 self.probe_single_bound_for_assoc_item(
1383 || {
1384 let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
1385 traits::supertraits(tcx, trait_ref)
1386 },
1387 AssocItemQSelf::SelfTyAlias,
1388 assoc_tag,
1389 segment.ident,
1390 span,
1391 None,
1392 )?
1393 }
1394 (
1395 &ty::Param(_),
1396 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1397 ) => self.probe_single_ty_param_bound_for_assoc_item(
1398 param_did.expect_local(),
1399 hir_self_ty.span,
1400 assoc_tag,
1401 segment.ident,
1402 span,
1403 )?,
1404 _ => {
1405 return Err(self.report_unresolved_type_relative_path(
1406 self_ty,
1407 hir_self_ty,
1408 assoc_tag,
1409 segment.ident,
1410 qpath_hir_id,
1411 span,
1412 variant_def_id,
1413 ));
1414 }
1415 };
1416
1417 let assoc_item = self
1418 .probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
1419 .expect("failed to find associated item");
1420
1421 Ok((assoc_item.def_id, bound))
1422 }
1423
1424 fn probe_inherent_assoc_item(
1426 &self,
1427 segment: &hir::PathSegment<'tcx>,
1428 adt_did: DefId,
1429 self_ty: Ty<'tcx>,
1430 block: HirId,
1431 span: Span,
1432 assoc_tag: ty::AssocTag,
1433 ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1434 let tcx = self.tcx();
1435
1436 if !tcx.features().inherent_associated_types() {
1437 match assoc_tag {
1438 ty::AssocTag::Type => return Ok(None),
1446 ty::AssocTag::Const => {
1447 return Err(feature_err(
1451 &tcx.sess,
1452 sym::inherent_associated_types,
1453 span,
1454 "inherent associated types are unstable",
1455 )
1456 .emit());
1457 }
1458 ty::AssocTag::Fn => unreachable!(),
1459 }
1460 }
1461
1462 let name = segment.ident;
1463 let candidates: Vec<_> = tcx
1464 .inherent_impls(adt_did)
1465 .iter()
1466 .filter_map(|&impl_| {
1467 let (item, scope) =
1468 self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1469 Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope })
1470 })
1471 .collect();
1472
1473 let (applicable_candidates, fulfillment_errors) =
1474 self.select_inherent_assoc_candidates(span, self_ty, candidates.clone());
1475
1476 let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } =
1477 match &applicable_candidates[..] {
1478 &[] => Err(self.report_unresolved_inherent_assoc_item(
1479 name,
1480 self_ty,
1481 candidates,
1482 fulfillment_errors,
1483 span,
1484 assoc_tag,
1485 )),
1486
1487 &[applicable_candidate] => Ok(applicable_candidate),
1488
1489 &[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
1490 name,
1491 candidates.into_iter().map(|cand| cand.assoc_item).collect(),
1492 span,
1493 )),
1494 }?;
1495
1496 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1497
1498 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1502 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1503 let args = tcx.mk_args_from_iter(
1504 std::iter::once(ty::GenericArg::from(self_ty))
1505 .chain(args.into_iter().skip(parent_args.len())),
1506 );
1507
1508 Ok(Some((assoc_item, args)))
1509 }
1510
1511 fn probe_assoc_item(
1515 &self,
1516 ident: Ident,
1517 assoc_tag: ty::AssocTag,
1518 block: HirId,
1519 span: Span,
1520 scope: DefId,
1521 ) -> Option<ty::AssocItem> {
1522 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1523 self.check_assoc_item(item.def_id, ident, scope, block, span);
1524 Some(item)
1525 }
1526
1527 fn probe_assoc_item_unchecked(
1532 &self,
1533 ident: Ident,
1534 assoc_tag: ty::AssocTag,
1535 block: HirId,
1536 scope: DefId,
1537 ) -> Option<(ty::AssocItem, DefId)> {
1538 let tcx = self.tcx();
1539
1540 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1541 let item = tcx
1545 .associated_items(scope)
1546 .filter_by_name_unhygienic(ident.name)
1547 .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1548
1549 Some((*item, def_scope))
1550 }
1551
1552 fn check_assoc_item(
1554 &self,
1555 item_def_id: DefId,
1556 ident: Ident,
1557 scope: DefId,
1558 block: HirId,
1559 span: Span,
1560 ) {
1561 let tcx = self.tcx();
1562
1563 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1564 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1565 span,
1566 kind: tcx.def_descr(item_def_id),
1567 name: ident,
1568 defined_here_label: tcx.def_span(item_def_id),
1569 });
1570 }
1571
1572 tcx.check_stability(item_def_id, Some(block), span, None);
1573 }
1574
1575 fn probe_traits_that_match_assoc_ty(
1576 &self,
1577 qself_ty: Ty<'tcx>,
1578 assoc_ident: Ident,
1579 ) -> Vec<String> {
1580 let tcx = self.tcx();
1581
1582 let infcx_;
1585 let infcx = if let Some(infcx) = self.infcx() {
1586 infcx
1587 } else {
1588 assert!(!qself_ty.has_infer());
1589 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1590 &infcx_
1591 };
1592
1593 tcx.all_traits_including_private()
1594 .filter(|trait_def_id| {
1595 tcx.associated_items(*trait_def_id)
1597 .in_definition_order()
1598 .any(|i| {
1599 i.is_type()
1600 && !i.is_impl_trait_in_trait()
1601 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1602 })
1603 && tcx.visibility(*trait_def_id)
1605 .is_accessible_from(self.item_def_id(), tcx)
1606 && tcx.all_impls(*trait_def_id)
1607 .any(|impl_def_id| {
1608 let header = tcx.impl_trait_header(impl_def_id).unwrap();
1609 let trait_ref = header.trait_ref.instantiate(
1610 tcx,
1611 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1612 );
1613
1614 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1615 if value.has_escaping_bound_vars() {
1617 return false;
1618 }
1619 infcx
1620 .can_eq(
1621 ty::ParamEnv::empty(),
1622 trait_ref.self_ty(),
1623 value,
1624 ) && header.polarity != ty::ImplPolarity::Negative
1625 })
1626 })
1627 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1628 .collect()
1629 }
1630
1631 #[instrument(level = "debug", skip_all)]
1633 fn lower_resolved_assoc_ty_path(
1634 &self,
1635 span: Span,
1636 opt_self_ty: Option<Ty<'tcx>>,
1637 item_def_id: DefId,
1638 trait_segment: Option<&hir::PathSegment<'tcx>>,
1639 item_segment: &hir::PathSegment<'tcx>,
1640 ) -> Ty<'tcx> {
1641 match self.lower_resolved_assoc_item_path(
1642 span,
1643 opt_self_ty,
1644 item_def_id,
1645 trait_segment,
1646 item_segment,
1647 ty::AssocTag::Type,
1648 ) {
1649 Ok((item_def_id, item_args)) => {
1650 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1651 }
1652 Err(guar) => Ty::new_error(self.tcx(), guar),
1653 }
1654 }
1655
1656 #[instrument(level = "debug", skip_all)]
1658 fn lower_resolved_assoc_const_path(
1659 &self,
1660 span: Span,
1661 opt_self_ty: Option<Ty<'tcx>>,
1662 item_def_id: DefId,
1663 trait_segment: Option<&hir::PathSegment<'tcx>>,
1664 item_segment: &hir::PathSegment<'tcx>,
1665 ) -> Const<'tcx> {
1666 match self.lower_resolved_assoc_item_path(
1667 span,
1668 opt_self_ty,
1669 item_def_id,
1670 trait_segment,
1671 item_segment,
1672 ty::AssocTag::Const,
1673 ) {
1674 Ok((item_def_id, item_args)) => {
1675 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1676 Const::new_unevaluated(self.tcx(), uv)
1677 }
1678 Err(guar) => Const::new_error(self.tcx(), guar),
1679 }
1680 }
1681
1682 #[instrument(level = "debug", skip_all)]
1684 fn lower_resolved_assoc_item_path(
1685 &self,
1686 span: Span,
1687 opt_self_ty: Option<Ty<'tcx>>,
1688 item_def_id: DefId,
1689 trait_segment: Option<&hir::PathSegment<'tcx>>,
1690 item_segment: &hir::PathSegment<'tcx>,
1691 assoc_tag: ty::AssocTag,
1692 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1693 let tcx = self.tcx();
1694
1695 let trait_def_id = tcx.parent(item_def_id);
1696 debug!(?trait_def_id);
1697
1698 let Some(self_ty) = opt_self_ty else {
1699 return Err(self.report_missing_self_ty_for_resolved_path(
1700 trait_def_id,
1701 span,
1702 item_segment,
1703 assoc_tag,
1704 ));
1705 };
1706 debug!(?self_ty);
1707
1708 let trait_ref =
1709 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
1710 debug!(?trait_ref);
1711
1712 let item_args =
1713 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1714
1715 Ok((item_def_id, item_args))
1716 }
1717
1718 pub fn prohibit_generic_args<'a>(
1719 &self,
1720 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1721 err_extend: GenericsArgsErrExtend<'a>,
1722 ) -> Result<(), ErrorGuaranteed> {
1723 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1724 let mut result = Ok(());
1725 if let Some(_) = args_visitors.clone().next() {
1726 result = Err(self.report_prohibited_generic_args(
1727 segments.clone(),
1728 args_visitors,
1729 err_extend,
1730 ));
1731 }
1732
1733 for segment in segments {
1734 if let Some(c) = segment.args().constraints.first() {
1736 return Err(prohibit_assoc_item_constraint(self, c, None));
1737 }
1738 }
1739
1740 result
1741 }
1742
1743 pub fn probe_generic_path_segments(
1761 &self,
1762 segments: &[hir::PathSegment<'_>],
1763 self_ty: Option<Ty<'tcx>>,
1764 kind: DefKind,
1765 def_id: DefId,
1766 span: Span,
1767 ) -> Vec<GenericPathSegment> {
1768 let tcx = self.tcx();
1814
1815 assert!(!segments.is_empty());
1816 let last = segments.len() - 1;
1817
1818 let mut generic_segments = vec![];
1819
1820 match kind {
1821 DefKind::Ctor(CtorOf::Struct, ..) => {
1823 let generics = tcx.generics_of(def_id);
1826 let generics_def_id = generics.parent.unwrap_or(def_id);
1829 generic_segments.push(GenericPathSegment(generics_def_id, last));
1830 }
1831
1832 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
1834 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
1835 let adt_def = self.probe_adt(span, self_ty).unwrap();
1836 debug_assert!(adt_def.is_enum());
1837 (adt_def.did(), last)
1838 } else if last >= 1 && segments[last - 1].args.is_some() {
1839 let mut def_id = def_id;
1842
1843 if let DefKind::Ctor(..) = kind {
1845 def_id = tcx.parent(def_id);
1846 }
1847
1848 let enum_def_id = tcx.parent(def_id);
1850 (enum_def_id, last - 1)
1851 } else {
1852 let generics = tcx.generics_of(def_id);
1858 (generics.parent.unwrap_or(def_id), last)
1861 };
1862 generic_segments.push(GenericPathSegment(generics_def_id, index));
1863 }
1864
1865 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
1867 generic_segments.push(GenericPathSegment(def_id, last));
1868 }
1869
1870 DefKind::AssocFn | DefKind::AssocConst => {
1872 if segments.len() >= 2 {
1873 let generics = tcx.generics_of(def_id);
1874 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
1875 }
1876 generic_segments.push(GenericPathSegment(def_id, last));
1877 }
1878
1879 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
1880 }
1881
1882 debug!(?generic_segments);
1883
1884 generic_segments
1885 }
1886
1887 #[instrument(level = "debug", skip_all)]
1889 pub fn lower_resolved_ty_path(
1890 &self,
1891 opt_self_ty: Option<Ty<'tcx>>,
1892 path: &hir::Path<'tcx>,
1893 hir_id: HirId,
1894 permit_variants: PermitVariants,
1895 ) -> Ty<'tcx> {
1896 debug!(?path.res, ?opt_self_ty, ?path.segments);
1897 let tcx = self.tcx();
1898
1899 let span = path.span;
1900 match path.res {
1901 Res::Def(DefKind::OpaqueTy, did) => {
1902 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
1904 let item_segment = path.segments.split_last().unwrap();
1905 let _ = self
1906 .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy);
1907 let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0);
1908 Ty::new_opaque(tcx, did, args)
1909 }
1910 Res::Def(
1911 DefKind::Enum
1912 | DefKind::TyAlias
1913 | DefKind::Struct
1914 | DefKind::Union
1915 | DefKind::ForeignTy,
1916 did,
1917 ) => {
1918 assert_eq!(opt_self_ty, None);
1919 let _ = self.prohibit_generic_args(
1920 path.segments.split_last().unwrap().1.iter(),
1921 GenericsArgsErrExtend::None,
1922 );
1923 self.lower_path_segment(span, did, path.segments.last().unwrap())
1924 }
1925 Res::Def(kind @ DefKind::Variant, def_id)
1926 if let PermitVariants::Yes = permit_variants =>
1927 {
1928 assert_eq!(opt_self_ty, None);
1931
1932 let generic_segments =
1933 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
1934 let indices: FxHashSet<_> =
1935 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
1936 let _ = self.prohibit_generic_args(
1937 path.segments.iter().enumerate().filter_map(|(index, seg)| {
1938 if !indices.contains(&index) { Some(seg) } else { None }
1939 }),
1940 GenericsArgsErrExtend::DefVariant(&path.segments),
1941 );
1942
1943 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
1944 self.lower_path_segment(span, *def_id, &path.segments[*index])
1945 }
1946 Res::Def(DefKind::TyParam, def_id) => {
1947 assert_eq!(opt_self_ty, None);
1948 let _ = self.prohibit_generic_args(
1949 path.segments.iter(),
1950 GenericsArgsErrExtend::Param(def_id),
1951 );
1952 self.lower_ty_param(hir_id)
1953 }
1954 Res::SelfTyParam { .. } => {
1955 assert_eq!(opt_self_ty, None);
1957 let _ = self.prohibit_generic_args(
1958 path.segments.iter(),
1959 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
1960 GenericsArgsErrExtend::SelfTyParam(
1961 ident.span.shrink_to_hi().to(args.span_ext),
1962 )
1963 } else {
1964 GenericsArgsErrExtend::None
1965 },
1966 );
1967 tcx.types.self_param
1968 }
1969 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
1970 assert_eq!(opt_self_ty, None);
1972 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
1974 let _ = self.prohibit_generic_args(
1975 path.segments.iter(),
1976 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
1977 );
1978 if forbid_generic && ty.has_param() {
1998 let mut err = self.dcx().struct_span_err(
1999 path.span,
2000 "generic `Self` types are currently not permitted in anonymous constants",
2001 );
2002 if let Some(hir::Node::Item(&hir::Item {
2003 kind: hir::ItemKind::Impl(impl_),
2004 ..
2005 })) = tcx.hir_get_if_local(def_id)
2006 {
2007 err.span_note(impl_.self_ty.span, "not a concrete type");
2008 }
2009 let reported = err.emit();
2010 Ty::new_error(tcx, reported)
2011 } else {
2012 ty
2013 }
2014 }
2015 Res::Def(DefKind::AssocTy, def_id) => {
2016 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2017 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2018 Some(trait_)
2019 } else {
2020 None
2021 };
2022 self.lower_resolved_assoc_ty_path(
2023 span,
2024 opt_self_ty,
2025 def_id,
2026 trait_segment,
2027 path.segments.last().unwrap(),
2028 )
2029 }
2030 Res::PrimTy(prim_ty) => {
2031 assert_eq!(opt_self_ty, None);
2032 let _ = self.prohibit_generic_args(
2033 path.segments.iter(),
2034 GenericsArgsErrExtend::PrimTy(prim_ty),
2035 );
2036 match prim_ty {
2037 hir::PrimTy::Bool => tcx.types.bool,
2038 hir::PrimTy::Char => tcx.types.char,
2039 hir::PrimTy::Int(it) => Ty::new_int(tcx, it),
2040 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, uit),
2041 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ft),
2042 hir::PrimTy::Str => tcx.types.str_,
2043 }
2044 }
2045 Res::Err => {
2046 let e = self
2047 .tcx()
2048 .dcx()
2049 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2050 Ty::new_error(tcx, e)
2051 }
2052 Res::Def(..) => {
2053 assert_eq!(
2054 path.segments.get(0).map(|seg| seg.ident.name),
2055 Some(kw::SelfUpper),
2056 "only expected incorrect resolution for `Self`"
2057 );
2058 Ty::new_error(
2059 self.tcx(),
2060 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2061 )
2062 }
2063 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2064 }
2065 }
2066
2067 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2072 let tcx = self.tcx();
2073 match tcx.named_bound_var(hir_id) {
2074 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2075 let br = ty::BoundTy {
2076 var: ty::BoundVar::from_u32(index),
2077 kind: ty::BoundTyKind::Param(def_id.to_def_id()),
2078 };
2079 Ty::new_bound(tcx, debruijn, br)
2080 }
2081 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2082 let item_def_id = tcx.hir_ty_param_owner(def_id);
2083 let generics = tcx.generics_of(item_def_id);
2084 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2085 Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2086 }
2087 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2088 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2089 }
2090 }
2091
2092 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2097 let tcx = self.tcx();
2098
2099 match tcx.named_bound_var(path_hir_id) {
2100 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2101 let item_def_id = tcx.parent(param_def_id);
2104 let generics = tcx.generics_of(item_def_id);
2105 let index = generics.param_def_id_to_index[¶m_def_id];
2106 let name = tcx.item_name(param_def_id);
2107 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2108 }
2109 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => ty::Const::new_bound(
2110 tcx,
2111 debruijn,
2112 ty::BoundConst { var: ty::BoundVar::from_u32(index) },
2113 ),
2114 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2115 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2116 }
2117 }
2118
2119 #[instrument(skip(self), level = "debug")]
2121 pub fn lower_const_arg(
2122 &self,
2123 const_arg: &hir::ConstArg<'tcx>,
2124 feed: FeedConstTy<'_, 'tcx>,
2125 ) -> Const<'tcx> {
2126 let tcx = self.tcx();
2127
2128 if let FeedConstTy::Param(param_def_id, args) = feed
2129 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2130 {
2131 let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2132
2133 if tcx.features().generic_const_parameter_types()
2142 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2143 {
2144 let e = self.dcx().span_err(
2145 const_arg.span(),
2146 "anonymous constants with lifetimes in their type are not yet supported",
2147 );
2148 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2149 return ty::Const::new_error(tcx, e);
2150 }
2151 if anon_const_type.has_non_region_infer() {
2155 let e = self.dcx().span_err(
2156 const_arg.span(),
2157 "anonymous constants with inferred types are not yet supported",
2158 );
2159 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2160 return ty::Const::new_error(tcx, e);
2161 }
2162 if anon_const_type.has_non_region_param() {
2165 let e = self.dcx().span_err(
2166 const_arg.span(),
2167 "anonymous constants referencing generics are not yet supported",
2168 );
2169 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2170 return ty::Const::new_error(tcx, e);
2171 }
2172
2173 tcx.feed_anon_const_type(
2174 anon.def_id,
2175 ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2176 );
2177 }
2178
2179 let hir_id = const_arg.hir_id;
2180 match const_arg.kind {
2181 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2182 debug!(?maybe_qself, ?path);
2183 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2184 self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2185 }
2186 hir::ConstArgKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2187 debug!(?hir_self_ty, ?segment);
2188 let self_ty = self.lower_ty(hir_self_ty);
2189 self.lower_type_relative_const_path(
2190 self_ty,
2191 hir_self_ty,
2192 segment,
2193 hir_id,
2194 const_arg.span(),
2195 )
2196 .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2197 }
2198 hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
2199 ty::Const::new_error_with_message(
2200 tcx,
2201 qpath.span(),
2202 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
2203 )
2204 }
2205 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2206 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2207 }
2208 }
2209
2210 fn lower_resolved_const_path(
2212 &self,
2213 opt_self_ty: Option<Ty<'tcx>>,
2214 path: &hir::Path<'tcx>,
2215 hir_id: HirId,
2216 ) -> Const<'tcx> {
2217 let tcx = self.tcx();
2218 let span = path.span;
2219 match path.res {
2220 Res::Def(DefKind::ConstParam, def_id) => {
2221 assert_eq!(opt_self_ty, None);
2222 let _ = self.prohibit_generic_args(
2223 path.segments.iter(),
2224 GenericsArgsErrExtend::Param(def_id),
2225 );
2226 self.lower_const_param(def_id, hir_id)
2227 }
2228 Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2229 assert_eq!(opt_self_ty, None);
2230 let _ = self.prohibit_generic_args(
2231 path.segments.split_last().unwrap().1.iter(),
2232 GenericsArgsErrExtend::None,
2233 );
2234 let args = self.lower_generic_args_of_path_segment(
2235 span,
2236 did,
2237 path.segments.last().unwrap(),
2238 );
2239 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2240 }
2241 Res::Def(DefKind::AssocConst, did) => {
2242 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2243 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2244 Some(trait_)
2245 } else {
2246 None
2247 };
2248 self.lower_resolved_assoc_const_path(
2249 span,
2250 opt_self_ty,
2251 did,
2252 trait_segment,
2253 path.segments.last().unwrap(),
2254 )
2255 }
2256 Res::Def(DefKind::Static { .. }, _) => {
2257 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2258 }
2259 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2261 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2262 let args = self.lower_generic_args_of_path_segment(
2263 span,
2264 did,
2265 path.segments.last().unwrap(),
2266 );
2267 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2268 }
2269
2270 res @ (Res::Def(
2273 DefKind::Mod
2274 | DefKind::Enum
2275 | DefKind::Variant
2276 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2277 | DefKind::Struct
2278 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2279 | DefKind::OpaqueTy
2280 | DefKind::TyAlias
2281 | DefKind::TraitAlias
2282 | DefKind::AssocTy
2283 | DefKind::Union
2284 | DefKind::Trait
2285 | DefKind::ForeignTy
2286 | DefKind::TyParam
2287 | DefKind::Macro(_)
2288 | DefKind::LifetimeParam
2289 | DefKind::Use
2290 | DefKind::ForeignMod
2291 | DefKind::AnonConst
2292 | DefKind::InlineConst
2293 | DefKind::Field
2294 | DefKind::Impl { .. }
2295 | DefKind::Closure
2296 | DefKind::ExternCrate
2297 | DefKind::GlobalAsm
2298 | DefKind::SyntheticCoroutineBody,
2299 _,
2300 )
2301 | Res::PrimTy(_)
2302 | Res::SelfTyParam { .. }
2303 | Res::SelfTyAlias { .. }
2304 | Res::SelfCtor(_)
2305 | Res::Local(_)
2306 | Res::ToolMod
2307 | Res::NonMacroAttr(_)
2308 | Res::Err) => Const::new_error_with_message(
2309 tcx,
2310 span,
2311 format!("invalid Res {res:?} for const path"),
2312 ),
2313 }
2314 }
2315
2316 #[instrument(skip(self), level = "debug")]
2318 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2319 let tcx = self.tcx();
2320
2321 let expr = &tcx.hir_body(anon.body).value;
2322 debug!(?expr);
2323
2324 let ty = tcx.type_of(anon.def_id).instantiate_identity();
2328
2329 match self.try_lower_anon_const_lit(ty, expr) {
2330 Some(v) => v,
2331 None => ty::Const::new_unevaluated(
2332 tcx,
2333 ty::UnevaluatedConst {
2334 def: anon.def_id.to_def_id(),
2335 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2336 },
2337 ),
2338 }
2339 }
2340
2341 #[instrument(skip(self), level = "debug")]
2342 fn try_lower_anon_const_lit(
2343 &self,
2344 ty: Ty<'tcx>,
2345 expr: &'tcx hir::Expr<'tcx>,
2346 ) -> Option<Const<'tcx>> {
2347 let tcx = self.tcx();
2348
2349 let expr = match &expr.kind {
2352 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2353 block.expr.as_ref().unwrap()
2354 }
2355 _ => expr,
2356 };
2357
2358 if let hir::ExprKind::Path(hir::QPath::Resolved(
2359 _,
2360 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2361 )) = expr.kind
2362 {
2363 span_bug!(
2364 expr.span,
2365 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2366 );
2367 };
2368
2369 let lit_input = match expr.kind {
2370 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: false }),
2371 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2372 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: true }),
2373 _ => None,
2374 },
2375 _ => None,
2376 };
2377
2378 lit_input
2379 .filter(|l| !l.ty.has_aliases())
2382 .map(|l| tcx.at(expr.span).lit_to_const(l))
2383 }
2384
2385 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2386 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2387 match idx {
2388 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2389 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2390 }
2391 }
2392
2393 #[instrument(level = "debug", skip(self), ret)]
2395 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2396 let tcx = self.tcx();
2397
2398 let result_ty = match &hir_ty.kind {
2399 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2400 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2401 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2402 hir::TyKind::Ref(region, mt) => {
2403 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2404 debug!(?r);
2405 let t = self.lower_ty(mt.ty);
2406 Ty::new_ref(tcx, r, t, mt.mutbl)
2407 }
2408 hir::TyKind::Never => tcx.types.never,
2409 hir::TyKind::Tup(fields) => {
2410 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2411 }
2412 hir::TyKind::FnPtr(bf) => {
2413 check_c_variadic_abi(tcx, bf.decl, bf.abi, hir_ty.span);
2414
2415 Ty::new_fn_ptr(
2416 tcx,
2417 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2418 )
2419 }
2420 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2421 tcx,
2422 ty::Binder::bind_with_vars(
2423 self.lower_ty(binder.inner_ty),
2424 tcx.late_bound_vars(hir_ty.hir_id),
2425 ),
2426 ),
2427 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2428 let lifetime = tagged_ptr.pointer();
2429 let syntax = tagged_ptr.tag();
2430 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, syntax)
2431 }
2432 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2436 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2437 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2438 }) =>
2439 {
2440 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2441 Ty::new_error(tcx, guar)
2442 }
2443 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2444 debug!(?maybe_qself, ?path);
2445 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2446 self.lower_resolved_ty_path(opt_self_ty, path, hir_ty.hir_id, PermitVariants::No)
2447 }
2448 &hir::TyKind::OpaqueDef(opaque_ty) => {
2449 let in_trait = match opaque_ty.origin {
2453 hir::OpaqueTyOrigin::FnReturn {
2454 parent,
2455 in_trait_or_impl: Some(hir::RpitContext::Trait),
2456 ..
2457 }
2458 | hir::OpaqueTyOrigin::AsyncFn {
2459 parent,
2460 in_trait_or_impl: Some(hir::RpitContext::Trait),
2461 ..
2462 } => Some(parent),
2463 hir::OpaqueTyOrigin::FnReturn {
2464 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2465 ..
2466 }
2467 | hir::OpaqueTyOrigin::AsyncFn {
2468 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2469 ..
2470 }
2471 | hir::OpaqueTyOrigin::TyAlias { .. } => None,
2472 };
2473
2474 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2475 }
2476 hir::TyKind::TraitAscription(hir_bounds) => {
2477 let self_ty = self.ty_infer(None, hir_ty.span);
2480 let mut bounds = Vec::new();
2481 self.lower_bounds(
2482 self_ty,
2483 hir_bounds.iter(),
2484 &mut bounds,
2485 ty::List::empty(),
2486 PredicateFilter::All,
2487 );
2488 self.add_sizedness_bounds(
2489 &mut bounds,
2490 self_ty,
2491 hir_bounds,
2492 None,
2493 None,
2494 hir_ty.span,
2495 );
2496 self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2497 self_ty
2498 }
2499 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2503 if segment.args.is_some_and(|args| {
2504 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2505 }) =>
2506 {
2507 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2508 Ty::new_error(tcx, guar)
2509 }
2510 hir::TyKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2511 debug!(?hir_self_ty, ?segment);
2512 let self_ty = self.lower_ty(hir_self_ty);
2513 self.lower_type_relative_ty_path(
2514 self_ty,
2515 hir_self_ty,
2516 segment,
2517 hir_ty.hir_id,
2518 hir_ty.span,
2519 PermitVariants::No,
2520 )
2521 .map(|(ty, _, _)| ty)
2522 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2523 }
2524 &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
2525 let def_id = tcx.require_lang_item(lang_item, span);
2526 let (args, _) = self.lower_generic_args_of_path(
2527 span,
2528 def_id,
2529 &[],
2530 &hir::PathSegment::invalid(),
2531 None,
2532 );
2533 tcx.at(span).type_of(def_id).instantiate(tcx, args)
2534 }
2535 hir::TyKind::Array(ty, length) => {
2536 let length = self.lower_const_arg(length, FeedConstTy::No);
2537 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2538 }
2539 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2540 hir::TyKind::Infer(()) => {
2541 self.ty_infer(None, hir_ty.span)
2546 }
2547 hir::TyKind::Pat(ty, pat) => {
2548 let ty_span = ty.span;
2549 let ty = self.lower_ty(ty);
2550 let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
2551 Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
2552 Err(guar) => Ty::new_error(tcx, guar),
2553 };
2554 self.record_ty(pat.hir_id, ty, pat.span);
2555 pat_ty
2556 }
2557 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2558 };
2559
2560 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2561 result_ty
2562 }
2563
2564 fn lower_pat_ty_pat(
2565 &self,
2566 ty: Ty<'tcx>,
2567 ty_span: Span,
2568 pat: &hir::TyPat<'tcx>,
2569 ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
2570 let tcx = self.tcx();
2571 match pat.kind {
2572 hir::TyPatKind::Range(start, end) => {
2573 match ty.kind() {
2574 ty::Int(_) | ty::Uint(_) | ty::Char => {
2577 let start = self.lower_const_arg(start, FeedConstTy::No);
2578 let end = self.lower_const_arg(end, FeedConstTy::No);
2579 Ok(ty::PatternKind::Range { start, end })
2580 }
2581 _ => Err(self
2582 .dcx()
2583 .span_delayed_bug(ty_span, "invalid base type for range pattern")),
2584 }
2585 }
2586 hir::TyPatKind::Or(patterns) => {
2587 self.tcx()
2588 .mk_patterns_from_iter(patterns.iter().map(|pat| {
2589 self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
2590 }))
2591 .map(ty::PatternKind::Or)
2592 }
2593 hir::TyPatKind::Err(e) => Err(e),
2594 }
2595 }
2596
2597 #[instrument(level = "debug", skip(self), ret)]
2599 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: Option<LocalDefId>) -> Ty<'tcx> {
2600 let tcx = self.tcx();
2601
2602 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2603 debug!(?lifetimes);
2604
2605 let def_id = if let Some(parent_def_id) = in_trait {
2609 *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
2610 .iter()
2611 .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
2612 Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
2613 opaque_def_id.expect_local() == def_id
2614 }
2615 _ => unreachable!(),
2616 })
2617 .unwrap()
2618 } else {
2619 def_id.to_def_id()
2620 };
2621
2622 let generics = tcx.generics_of(def_id);
2623 debug!(?generics);
2624
2625 let offset = generics.count() - lifetimes.len();
2629
2630 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2631 if let Some(i) = (param.index as usize).checked_sub(offset) {
2632 let (lifetime, _) = lifetimes[i];
2633 self.lower_resolved_lifetime(lifetime).into()
2634 } else {
2635 tcx.mk_param_from_def(param)
2636 }
2637 });
2638 debug!(?args);
2639
2640 if in_trait.is_some() {
2641 Ty::new_projection_from_args(tcx, def_id, args)
2642 } else {
2643 Ty::new_opaque(tcx, def_id, args)
2644 }
2645 }
2646
2647 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2649 pub fn lower_fn_ty(
2650 &self,
2651 hir_id: HirId,
2652 safety: hir::Safety,
2653 abi: rustc_abi::ExternAbi,
2654 decl: &hir::FnDecl<'tcx>,
2655 generics: Option<&hir::Generics<'_>>,
2656 hir_ty: Option<&hir::Ty<'_>>,
2657 ) -> ty::PolyFnSig<'tcx> {
2658 let tcx = self.tcx();
2659 let bound_vars = tcx.late_bound_vars(hir_id);
2660 debug!(?bound_vars);
2661
2662 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2663
2664 debug!(?output_ty);
2665
2666 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2667 let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2668
2669 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), span, .. }) =
2670 tcx.hir_node(hir_id)
2671 {
2672 check_abi(tcx, hir_id, *span, fn_ptr_ty.abi);
2673 }
2674
2675 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, fn_ptr_ty);
2677
2678 if !fn_ptr_ty.references_error() {
2679 let inputs = fn_ptr_ty.inputs();
2686 let late_bound_in_args =
2687 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2688 let output = fn_ptr_ty.output();
2689 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2690
2691 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2692 struct_span_code_err!(
2693 self.dcx(),
2694 decl.output.span(),
2695 E0581,
2696 "return type references {}, which is not constrained by the fn input types",
2697 br_name
2698 )
2699 });
2700 }
2701
2702 fn_ptr_ty
2703 }
2704
2705 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2710 &self,
2711 fn_hir_id: HirId,
2712 arg_idx: Option<usize>,
2713 ) -> Option<Ty<'tcx>> {
2714 let tcx = self.tcx();
2715 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2716 tcx.hir_node(fn_hir_id)
2717 else {
2718 return None;
2719 };
2720 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2721
2722 let trait_ref = self.lower_impl_trait_ref(&i.of_trait?.trait_ref, self.lower_ty(i.self_ty));
2723
2724 let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
2725 tcx,
2726 *ident,
2727 ty::AssocTag::Fn,
2728 trait_ref.def_id,
2729 )?;
2730
2731 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2732 tcx,
2733 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2734 );
2735 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2736
2737 Some(if let Some(arg_idx) = arg_idx {
2738 *fn_sig.inputs().get(arg_idx)?
2739 } else {
2740 fn_sig.output()
2741 })
2742 }
2743
2744 #[instrument(level = "trace", skip(self, generate_err))]
2745 fn validate_late_bound_regions<'cx>(
2746 &'cx self,
2747 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2748 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2749 generate_err: impl Fn(&str) -> Diag<'cx>,
2750 ) {
2751 for br in referenced_regions.difference(&constrained_regions) {
2752 let br_name = if let Some(name) = br.get_name(self.tcx()) {
2753 format!("lifetime `{name}`")
2754 } else {
2755 "an anonymous lifetime".to_string()
2756 };
2757
2758 let mut err = generate_err(&br_name);
2759
2760 if !br.is_named(self.tcx()) {
2761 err.note(
2768 "lifetimes appearing in an associated or opaque type are not considered constrained",
2769 );
2770 err.note("consider introducing a named lifetime parameter");
2771 }
2772
2773 err.emit();
2774 }
2775 }
2776
2777 #[instrument(level = "debug", skip(self, span), ret)]
2785 fn compute_object_lifetime_bound(
2786 &self,
2787 span: Span,
2788 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2789 ) -> Option<ty::Region<'tcx>> {
2791 let tcx = self.tcx();
2792
2793 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2796
2797 if derived_region_bounds.is_empty() {
2800 return None;
2801 }
2802
2803 if derived_region_bounds.iter().any(|r| r.is_static()) {
2806 return Some(tcx.lifetimes.re_static);
2807 }
2808
2809 let r = derived_region_bounds[0];
2813 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2814 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2815 }
2816 Some(r)
2817 }
2818}