1mod bounds;
17mod cmse;
18mod dyn_compatibility;
19pub mod errors;
20pub mod generics;
21mod lint;
22
23use std::assert_matches::assert_matches;
24use std::slice;
25
26use rustc_ast::TraitObjectSyntax;
27use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
28use rustc_errors::codes::*;
29use rustc_errors::{
30 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
31};
32use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
33use rustc_hir::def_id::{DefId, LocalDefId};
34use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
35use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
36use rustc_infer::traits::ObligationCause;
37use rustc_middle::middle::stability::AllowUnstable;
38use rustc_middle::mir::interpret::LitToConstInput;
39use rustc_middle::ty::fold::fold_regions;
40use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
41use rustc_middle::ty::{
42 self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
43 TypeVisitableExt, TypingMode,
44};
45use rustc_middle::{bug, span_bug};
46use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
47use rustc_span::edit_distance::find_best_match_for_name;
48use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
49use rustc_trait_selection::infer::InferCtxtExt;
50use rustc_trait_selection::traits::wf::object_region_bounds;
51use rustc_trait_selection::traits::{self, ObligationCtxt};
52use tracing::{debug, instrument};
53
54use crate::bounds::Bounds;
55use crate::check::check_abi_fn_ptr;
56use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType};
57use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
58use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
59use crate::middle::resolve_bound_vars as rbv;
60use crate::require_c_abi_if_c_variadic;
61
62#[derive(Debug)]
64pub struct GenericPathSegment(pub DefId, pub usize);
65
66#[derive(Copy, Clone, Debug)]
67pub enum PredicateFilter {
68 All,
70
71 SelfOnly,
73
74 SelfTraitThatDefines(Ident),
78
79 SelfAndAssociatedTypeBounds,
83
84 ConstIfConst,
86
87 SelfConstIfConst,
89}
90
91#[derive(Debug)]
92pub enum RegionInferReason<'a> {
93 ExplicitObjectLifetime,
95 ObjectLifetimeDefault,
97 Param(&'a ty::GenericParamDef),
99 RegionPredicate,
100 Reference,
101 OutlivesBound,
102}
103
104pub trait HirTyLowerer<'tcx> {
109 fn tcx(&self) -> TyCtxt<'tcx>;
110
111 fn dcx(&self) -> DiagCtxtHandle<'_>;
112
113 fn item_def_id(&self) -> LocalDefId;
115
116 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
118
119 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
121
122 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
124
125 fn register_trait_ascription_bounds(
126 &self,
127 bounds: Vec<(ty::Clause<'tcx>, Span)>,
128 hir_id: HirId,
129 span: Span,
130 );
131
132 fn probe_ty_param_bounds(
147 &self,
148 span: Span,
149 def_id: LocalDefId,
150 assoc_name: Ident,
151 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
152
153 fn lower_assoc_ty(
166 &self,
167 span: Span,
168 item_def_id: DefId,
169 item_segment: &hir::PathSegment<'tcx>,
170 poly_trait_ref: ty::PolyTraitRef<'tcx>,
171 ) -> Ty<'tcx>;
172
173 fn lower_fn_sig(
174 &self,
175 decl: &hir::FnDecl<'tcx>,
176 generics: Option<&hir::Generics<'_>>,
177 hir_id: HirId,
178 hir_ty: Option<&hir::Ty<'_>>,
179 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
180
181 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
188
189 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
191
192 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
194
195 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
200 where
201 Self: Sized,
202 {
203 self
204 }
205}
206
207enum AssocItemQSelf {
211 Trait(DefId),
212 TyParam(LocalDefId, Span),
213 SelfTyAlias,
214}
215
216impl AssocItemQSelf {
217 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
218 match *self {
219 Self::Trait(def_id) => tcx.def_path_str(def_id),
220 Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(),
221 Self::SelfTyAlias => kw::SelfUpper.to_string(),
222 }
223 }
224}
225
226#[derive(Debug, Clone, Copy)]
233pub enum FeedConstTy {
234 Param(DefId),
239 No,
241}
242
243#[derive(Copy, Clone, PartialEq, Debug)]
253pub enum ExplicitLateBound {
254 Yes,
255 No,
256}
257
258#[derive(Copy, Clone, PartialEq)]
259pub enum IsMethodCall {
260 Yes,
261 No,
262}
263
264#[derive(Copy, Clone, PartialEq)]
267pub(crate) enum GenericArgPosition {
268 Type,
269 Value, MethodCall,
271}
272
273#[derive(Clone, Debug)]
276pub struct GenericArgCountMismatch {
277 pub reported: ErrorGuaranteed,
278 pub invalid_args: Vec<usize>,
280}
281
282#[derive(Clone, Debug)]
285pub struct GenericArgCountResult {
286 pub explicit_late_bound: ExplicitLateBound,
287 pub correct: Result<(), GenericArgCountMismatch>,
288}
289
290pub trait GenericArgsLowerer<'a, 'tcx> {
295 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
296
297 fn provided_kind(
298 &mut self,
299 param: &ty::GenericParamDef,
300 arg: &GenericArg<'tcx>,
301 ) -> ty::GenericArg<'tcx>;
302
303 fn inferred_kind(
304 &mut self,
305 preceding_args: &[ty::GenericArg<'tcx>],
306 param: &ty::GenericParamDef,
307 infer_args: bool,
308 ) -> ty::GenericArg<'tcx>;
309}
310
311impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
312 #[instrument(level = "debug", skip(self), ret)]
314 pub fn lower_lifetime(
315 &self,
316 lifetime: &hir::Lifetime,
317 reason: RegionInferReason<'_>,
318 ) -> ty::Region<'tcx> {
319 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
320 self.lower_resolved_lifetime(resolved)
321 } else {
322 self.re_infer(lifetime.ident.span, reason)
323 }
324 }
325
326 #[instrument(level = "debug", skip(self), ret)]
328 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
329 let tcx = self.tcx();
330 let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
331
332 match resolved {
333 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
334
335 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
336 let name = lifetime_name(def_id);
337 let br = ty::BoundRegion {
338 var: ty::BoundVar::from_u32(index),
339 kind: ty::BoundRegionKind::Named(def_id.to_def_id(), name),
340 };
341 ty::Region::new_bound(tcx, debruijn, br)
342 }
343
344 rbv::ResolvedArg::EarlyBound(def_id) => {
345 let name = tcx.hir().ty_param_name(def_id);
346 let item_def_id = tcx.hir().ty_param_owner(def_id);
347 let generics = tcx.generics_of(item_def_id);
348 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
349 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
350 }
351
352 rbv::ResolvedArg::Free(scope, id) => {
353 let name = lifetime_name(id);
354 ty::Region::new_late_param(
355 tcx,
356 scope.to_def_id(),
357 ty::LateParamRegionKind::Named(id.to_def_id(), name),
358 )
359
360 }
362
363 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
364 }
365 }
366
367 pub fn lower_generic_args_of_path_segment(
368 &self,
369 span: Span,
370 def_id: DefId,
371 item_segment: &hir::PathSegment<'tcx>,
372 ) -> GenericArgsRef<'tcx> {
373 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
374 if let Some(c) = item_segment.args().constraints.first() {
375 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
376 }
377 args
378 }
379
380 #[instrument(level = "debug", skip(self, span), ret)]
415 fn lower_generic_args_of_path(
416 &self,
417 span: Span,
418 def_id: DefId,
419 parent_args: &[ty::GenericArg<'tcx>],
420 segment: &hir::PathSegment<'tcx>,
421 self_ty: Option<Ty<'tcx>>,
422 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
423 let tcx = self.tcx();
428 let generics = tcx.generics_of(def_id);
429 debug!(?generics);
430
431 if generics.has_self {
432 if generics.parent.is_some() {
433 assert!(!parent_args.is_empty())
436 } else {
437 assert!(self_ty.is_some());
439 }
440 } else {
441 assert!(self_ty.is_none());
442 }
443
444 let arg_count = check_generic_arg_count(
445 self,
446 def_id,
447 segment,
448 generics,
449 GenericArgPosition::Type,
450 self_ty.is_some(),
451 );
452
453 if generics.is_own_empty() {
458 return (tcx.mk_args(parent_args), arg_count);
459 }
460
461 struct GenericArgsCtxt<'a, 'tcx> {
462 lowerer: &'a dyn HirTyLowerer<'tcx>,
463 def_id: DefId,
464 generic_args: &'a GenericArgs<'tcx>,
465 span: Span,
466 infer_args: bool,
467 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
468 }
469
470 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
471 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
472 if did == self.def_id {
473 (Some(self.generic_args), self.infer_args)
474 } else {
475 (None, false)
477 }
478 }
479
480 fn provided_kind(
481 &mut self,
482 param: &ty::GenericParamDef,
483 arg: &GenericArg<'tcx>,
484 ) -> ty::GenericArg<'tcx> {
485 let tcx = self.lowerer.tcx();
486
487 if let Err(incorrect) = self.incorrect_args {
488 if incorrect.invalid_args.contains(&(param.index as usize)) {
489 return param.to_error(tcx);
490 }
491 }
492
493 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
494 if has_default {
495 tcx.check_optional_stability(
496 param.def_id,
497 Some(arg.hir_id()),
498 arg.span(),
499 None,
500 AllowUnstable::No,
501 |_, _| {
502 },
508 );
509 }
510 self.lowerer.lower_ty(ty).into()
511 };
512
513 match (¶m.kind, arg) {
514 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
515 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
516 }
517 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
518 handle_ty_args(has_default, ty.as_unambig_ty())
520 }
521 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
522 handle_ty_args(has_default, &inf.to_ty())
523 }
524 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
525 .lowerer
526 .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
528 .into(),
529 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
530 self.lowerer.ct_infer(Some(param), inf.span).into()
531 }
532 (kind, arg) => span_bug!(
533 self.span,
534 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
535 ),
536 }
537 }
538
539 fn inferred_kind(
540 &mut self,
541 preceding_args: &[ty::GenericArg<'tcx>],
542 param: &ty::GenericParamDef,
543 infer_args: bool,
544 ) -> ty::GenericArg<'tcx> {
545 let tcx = self.lowerer.tcx();
546
547 if let Err(incorrect) = self.incorrect_args {
548 if incorrect.invalid_args.contains(&(param.index as usize)) {
549 return param.to_error(tcx);
550 }
551 }
552 match param.kind {
553 GenericParamDefKind::Lifetime => {
554 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
555 }
556 GenericParamDefKind::Type { has_default, .. } => {
557 if !infer_args && has_default {
558 if let Some(prev) =
560 preceding_args.iter().find_map(|arg| match arg.unpack() {
561 GenericArgKind::Type(ty) => ty.error_reported().err(),
562 _ => None,
563 })
564 {
565 return Ty::new_error(tcx, prev).into();
567 }
568 tcx.at(self.span)
569 .type_of(param.def_id)
570 .instantiate(tcx, preceding_args)
571 .into()
572 } else if infer_args {
573 self.lowerer.ty_infer(Some(param), self.span).into()
574 } else {
575 Ty::new_misc_error(tcx).into()
577 }
578 }
579 GenericParamDefKind::Const { has_default, .. } => {
580 let ty = tcx
581 .at(self.span)
582 .type_of(param.def_id)
583 .no_bound_vars()
584 .expect("const parameter types cannot be generic");
585 if let Err(guar) = ty.error_reported() {
586 return ty::Const::new_error(tcx, guar).into();
587 }
588 if !infer_args && has_default {
589 tcx.const_param_default(param.def_id)
590 .instantiate(tcx, preceding_args)
591 .into()
592 } else if infer_args {
593 self.lowerer.ct_infer(Some(param), self.span).into()
594 } else {
595 ty::Const::new_misc_error(tcx).into()
597 }
598 }
599 }
600 }
601 }
602
603 let mut args_ctx = GenericArgsCtxt {
604 lowerer: self,
605 def_id,
606 span,
607 generic_args: segment.args(),
608 infer_args: segment.infer_args,
609 incorrect_args: &arg_count.correct,
610 };
611 let args = lower_generic_args(
612 self,
613 def_id,
614 parent_args,
615 self_ty.is_some(),
616 self_ty,
617 &arg_count,
618 &mut args_ctx,
619 );
620
621 (args, arg_count)
622 }
623
624 #[instrument(level = "debug", skip_all)]
625 pub fn lower_generic_args_of_assoc_item(
626 &self,
627 span: Span,
628 item_def_id: DefId,
629 item_segment: &hir::PathSegment<'tcx>,
630 parent_args: GenericArgsRef<'tcx>,
631 ) -> GenericArgsRef<'tcx> {
632 debug!(?span, ?item_def_id, ?item_segment);
633 let (args, _) =
634 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
635 if let Some(c) = item_segment.args().constraints.first() {
636 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
637 }
638 args
639 }
640
641 pub fn lower_impl_trait_ref(
645 &self,
646 trait_ref: &hir::TraitRef<'tcx>,
647 self_ty: Ty<'tcx>,
648 ) -> ty::TraitRef<'tcx> {
649 let _ = self.prohibit_generic_args(
650 trait_ref.path.segments.split_last().unwrap().1.iter(),
651 GenericsArgsErrExtend::None,
652 );
653
654 self.lower_mono_trait_ref(
655 trait_ref.path.span,
656 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
657 self_ty,
658 trait_ref.path.segments.last().unwrap(),
659 true,
660 )
661 }
662
663 #[instrument(level = "debug", skip(self, span, constness, bounds))]
687 pub(crate) fn lower_poly_trait_ref(
688 &self,
689 trait_ref: &hir::TraitRef<'tcx>,
690 span: Span,
691 constness: hir::BoundConstness,
692 polarity: hir::BoundPolarity,
693 self_ty: Ty<'tcx>,
694 bounds: &mut Bounds<'tcx>,
695 predicate_filter: PredicateFilter,
696 ) -> GenericArgCountResult {
697 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
698 let trait_segment = trait_ref.path.segments.last().unwrap();
699
700 let _ = self.prohibit_generic_args(
701 trait_ref.path.segments.split_last().unwrap().1.iter(),
702 GenericsArgsErrExtend::None,
703 );
704 self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
705
706 let (generic_args, arg_count) = self.lower_generic_args_of_path(
707 trait_ref.path.span,
708 trait_def_id,
709 &[],
710 trait_segment,
711 Some(self_ty),
712 );
713
714 let tcx = self.tcx();
715 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
716 debug!(?bound_vars);
717
718 let poly_trait_ref = ty::Binder::bind_with_vars(
719 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
720 bound_vars,
721 );
722
723 let polarity = match polarity {
724 rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
725 rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
726 rustc_ast::BoundPolarity::Maybe(_) => {
727 for constraint in trait_segment.args().constraints {
730 let _ = self.lower_assoc_item_constraint(
731 trait_ref.hir_ref_id,
732 poly_trait_ref,
733 constraint,
734 &mut Default::default(),
735 &mut Default::default(),
736 constraint.span,
737 predicate_filter,
738 );
739 }
740 return arg_count;
741 }
742 };
743
744 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
745 && !self.tcx().is_const_trait(trait_def_id)
746 {
747 let (def_span, suggestion, suggestion_pre) =
748 match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) {
749 (true, true) => (
750 None,
751 Some(tcx.def_span(trait_def_id).shrink_to_lo()),
752 if self.tcx().features().const_trait_impl() {
753 ""
754 } else {
755 "enable `#![feature(const_trait_impl)]` in your crate and "
756 },
757 ),
758 (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
759 };
760 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
761 span,
762 modifier: constness.as_str(),
763 def_span,
764 trait_name: self.tcx().def_path_str(trait_def_id),
765 suggestion_pre,
766 suggestion,
767 });
768 }
769
770 match predicate_filter {
771 PredicateFilter::SelfTraitThatDefines(..) => {
773 bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
774 }
775 PredicateFilter::All
776 | PredicateFilter::SelfOnly
777 | PredicateFilter::SelfAndAssociatedTypeBounds => {
778 debug!(?poly_trait_ref);
779 bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
780
781 match constness {
782 hir::BoundConstness::Always(span) => {
783 if polarity == ty::PredicatePolarity::Positive {
784 bounds.push_const_bound(
785 tcx,
786 poly_trait_ref,
787 ty::BoundConstness::Const,
788 span,
789 );
790 }
791 }
792 hir::BoundConstness::Maybe(_) => {
793 }
798 hir::BoundConstness::Never => {}
799 }
800 }
801 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness {
808 hir::BoundConstness::Maybe(span) => {
809 if polarity == ty::PredicatePolarity::Positive {
810 bounds.push_const_bound(
811 tcx,
812 poly_trait_ref,
813 ty::BoundConstness::Maybe,
814 span,
815 );
816 }
817 }
818 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
819 },
820 }
821
822 let mut dup_constraints = FxIndexMap::default();
823 for constraint in trait_segment.args().constraints {
824 if polarity != ty::PredicatePolarity::Positive {
828 self.dcx().span_delayed_bug(
829 constraint.span,
830 "negative trait bounds should not have assoc item constraints",
831 );
832 break;
833 }
834
835 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
837 trait_ref.hir_ref_id,
838 poly_trait_ref,
839 constraint,
840 bounds,
841 &mut dup_constraints,
842 constraint.span,
843 predicate_filter,
844 );
845 }
847
848 arg_count
849 }
850
851 fn lower_mono_trait_ref(
855 &self,
856 span: Span,
857 trait_def_id: DefId,
858 self_ty: Ty<'tcx>,
859 trait_segment: &hir::PathSegment<'tcx>,
860 is_impl: bool,
861 ) -> ty::TraitRef<'tcx> {
862 self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
863
864 let (generic_args, _) =
865 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
866 if let Some(c) = trait_segment.args().constraints.first() {
867 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
868 }
869 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
870 }
871
872 fn probe_trait_that_defines_assoc_item(
873 &self,
874 trait_def_id: DefId,
875 assoc_kind: ty::AssocKind,
876 assoc_name: Ident,
877 ) -> bool {
878 self.tcx()
879 .associated_items(trait_def_id)
880 .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id)
881 .is_some()
882 }
883
884 fn lower_path_segment(
885 &self,
886 span: Span,
887 did: DefId,
888 item_segment: &hir::PathSegment<'tcx>,
889 ) -> Ty<'tcx> {
890 let tcx = self.tcx();
891 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
892
893 if let DefKind::TyAlias = tcx.def_kind(did)
894 && tcx.type_alias_is_lazy(did)
895 {
896 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
900 Ty::new_alias(tcx, ty::Weak, alias_ty)
901 } else {
902 tcx.at(span).type_of(did).instantiate(tcx, args)
903 }
904 }
905
906 #[instrument(level = "debug", skip_all, ret)]
914 fn probe_single_ty_param_bound_for_assoc_item(
915 &self,
916 ty_param_def_id: LocalDefId,
917 ty_param_span: Span,
918 kind: ty::AssocKind,
919 assoc_name: Ident,
920 span: Span,
921 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
922 debug!(?ty_param_def_id, ?assoc_name, ?span);
923 let tcx = self.tcx();
924
925 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name);
926 debug!("predicates={:#?}", predicates);
927
928 self.probe_single_bound_for_assoc_item(
929 || {
930 let trait_refs = predicates
931 .iter_identity_copied()
932 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
933 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
934 },
935 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
936 kind,
937 assoc_name,
938 span,
939 None,
940 )
941 }
942
943 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
948 fn probe_single_bound_for_assoc_item<I>(
949 &self,
950 all_candidates: impl Fn() -> I,
951 qself: AssocItemQSelf,
952 assoc_kind: ty::AssocKind,
953 assoc_name: Ident,
954 span: Span,
955 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
956 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
957 where
958 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
959 {
960 let tcx = self.tcx();
961
962 let mut matching_candidates = all_candidates().filter(|r| {
963 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_name)
964 });
965
966 let Some(bound) = matching_candidates.next() else {
967 let reported = self.complain_about_assoc_item_not_found(
968 all_candidates,
969 qself,
970 assoc_kind,
971 assoc_name,
972 span,
973 constraint,
974 );
975 return Err(reported);
976 };
977 debug!(?bound);
978
979 if let Some(bound2) = matching_candidates.next() {
980 debug!(?bound2);
981
982 let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
983 let qself_str = qself.to_string(tcx);
984 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
985 span,
986 assoc_kind: assoc_kind_str,
987 assoc_name,
988 qself: &qself_str,
989 });
990 err.code(
992 if let Some(constraint) = constraint
993 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
994 {
995 E0222
996 } else {
997 E0221
998 },
999 );
1000
1001 let mut where_bounds = vec![];
1004 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1005 let bound_id = bound.def_id();
1006 let bound_span = tcx
1007 .associated_items(bound_id)
1008 .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
1009 .and_then(|item| tcx.hir().span_if_local(item.def_id));
1010
1011 if let Some(bound_span) = bound_span {
1012 err.span_label(
1013 bound_span,
1014 format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
1015 );
1016 if let Some(constraint) = constraint {
1017 match constraint.kind {
1018 hir::AssocItemConstraintKind::Equality { term } => {
1019 let term: ty::Term<'_> = match term {
1020 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1021 hir::Term::Const(ct) => {
1022 self.lower_const_arg(ct, FeedConstTy::No).into()
1023 }
1024 };
1025 if term.references_error() {
1026 continue;
1027 }
1028 where_bounds.push(format!(
1030 " T: {trait}::{assoc_name} = {term}",
1031 trait = bound.print_only_trait_path(),
1032 ));
1033 }
1034 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1036 }
1037 } else {
1038 err.span_suggestion_verbose(
1039 span.with_hi(assoc_name.span.lo()),
1040 "use fully-qualified syntax to disambiguate",
1041 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1042 Applicability::MaybeIncorrect,
1043 );
1044 }
1045 } else {
1046 err.note(format!(
1047 "associated {assoc_kind_str} `{assoc_name}` could derive from `{}`",
1048 bound.print_only_trait_path(),
1049 ));
1050 }
1051 }
1052 if !where_bounds.is_empty() {
1053 err.help(format!(
1054 "consider introducing a new type parameter `T` and adding `where` constraints:\
1055 \n where\n T: {qself_str},\n{}",
1056 where_bounds.join(",\n"),
1057 ));
1058 let reported = err.emit();
1059 return Err(reported);
1060 }
1061 err.emit();
1062 }
1063
1064 Ok(bound)
1065 }
1066
1067 #[instrument(level = "debug", skip_all, ret)]
1095 pub fn lower_assoc_path(
1096 &self,
1097 hir_ref_id: HirId,
1098 span: Span,
1099 qself_ty: Ty<'tcx>,
1100 qself: &'tcx hir::Ty<'tcx>,
1101 assoc_segment: &'tcx hir::PathSegment<'tcx>,
1102 permit_variants: bool,
1103 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1104 debug!(%qself_ty, ?assoc_segment.ident);
1105 let tcx = self.tcx();
1106
1107 let assoc_ident = assoc_segment.ident;
1108
1109 let mut variant_resolution = None;
1111 if let Some(adt_def) = self.probe_adt(span, qself_ty) {
1112 if adt_def.is_enum() {
1113 let variant_def = adt_def
1114 .variants()
1115 .iter()
1116 .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
1117 if let Some(variant_def) = variant_def {
1118 if permit_variants {
1119 tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
1120 let _ = self.prohibit_generic_args(
1121 slice::from_ref(assoc_segment).iter(),
1122 GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def },
1123 );
1124 return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
1125 } else {
1126 variant_resolution = Some(variant_def.def_id);
1127 }
1128 }
1129 }
1130
1131 if let Some((ty, did)) = self.probe_inherent_assoc_ty(
1133 assoc_ident,
1134 assoc_segment,
1135 adt_def.did(),
1136 qself_ty,
1137 hir_ref_id,
1138 span,
1139 )? {
1140 return Ok((ty, DefKind::AssocTy, did));
1141 }
1142 }
1143
1144 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
1145 path.res
1146 } else {
1147 Res::Err
1148 };
1149
1150 let bound = match (qself_ty.kind(), qself_res) {
1153 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1154 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1157 self.dcx().span_bug(span, "expected cycle error");
1159 };
1160
1161 self.probe_single_bound_for_assoc_item(
1162 || {
1163 traits::supertraits(
1164 tcx,
1165 ty::Binder::dummy(trait_ref.instantiate_identity()),
1166 )
1167 },
1168 AssocItemQSelf::SelfTyAlias,
1169 ty::AssocKind::Type,
1170 assoc_ident,
1171 span,
1172 None,
1173 )?
1174 }
1175 (
1176 &ty::Param(_),
1177 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1178 ) => self.probe_single_ty_param_bound_for_assoc_item(
1179 param_did.expect_local(),
1180 qself.span,
1181 ty::AssocKind::Type,
1182 assoc_ident,
1183 span,
1184 )?,
1185 _ => {
1186 let reported = if variant_resolution.is_some() {
1187 let msg = format!("expected type, found variant `{assoc_ident}`");
1189 self.dcx().span_err(span, msg)
1190 } else if qself_ty.is_enum() {
1191 let mut err = struct_span_code_err!(
1192 self.dcx(),
1193 assoc_ident.span,
1194 E0599,
1195 "no variant named `{}` found for enum `{}`",
1196 assoc_ident,
1197 qself_ty,
1198 );
1199
1200 let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
1201 if let Some(variant_name) = find_best_match_for_name(
1202 &adt_def
1203 .variants()
1204 .iter()
1205 .map(|variant| variant.name)
1206 .collect::<Vec<Symbol>>(),
1207 assoc_ident.name,
1208 None,
1209 ) && let Some(variant) =
1210 adt_def.variants().iter().find(|s| s.name == variant_name)
1211 {
1212 let mut suggestion = vec![(assoc_ident.span, variant_name.to_string())];
1213 if let hir::Node::Stmt(hir::Stmt {
1214 kind: hir::StmtKind::Semi(ref expr),
1215 ..
1216 })
1217 | hir::Node::Expr(ref expr) = tcx.parent_hir_node(hir_ref_id)
1218 && let hir::ExprKind::Struct(..) = expr.kind
1219 {
1220 match variant.ctor {
1221 None => {
1222 suggestion = vec![(
1224 assoc_ident.span.with_hi(expr.span.hi()),
1225 if variant.fields.is_empty() {
1226 format!("{variant_name} {{}}")
1227 } else {
1228 format!(
1229 "{variant_name} {{ {} }}",
1230 variant
1231 .fields
1232 .iter()
1233 .map(|f| format!("{}: /* value */", f.name))
1234 .collect::<Vec<_>>()
1235 .join(", ")
1236 )
1237 },
1238 )];
1239 }
1240 Some((hir::def::CtorKind::Fn, def_id)) => {
1241 let fn_sig = tcx.fn_sig(def_id).instantiate_identity();
1243 let inputs = fn_sig.inputs().skip_binder();
1244 suggestion = vec![(
1245 assoc_ident.span.with_hi(expr.span.hi()),
1246 format!(
1247 "{variant_name}({})",
1248 inputs
1249 .iter()
1250 .map(|i| format!("/* {i} */"))
1251 .collect::<Vec<_>>()
1252 .join(", ")
1253 ),
1254 )];
1255 }
1256 Some((hir::def::CtorKind::Const, _)) => {
1257 suggestion = vec![(
1259 assoc_ident.span.with_hi(expr.span.hi()),
1260 variant_name.to_string(),
1261 )];
1262 }
1263 }
1264 }
1265 err.multipart_suggestion_verbose(
1266 "there is a variant with a similar name",
1267 suggestion,
1268 Applicability::HasPlaceholders,
1269 );
1270 } else {
1271 err.span_label(
1272 assoc_ident.span,
1273 format!("variant not found in `{qself_ty}`"),
1274 );
1275 }
1276
1277 if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
1278 err.span_label(sp, format!("variant `{assoc_ident}` not found here"));
1279 }
1280
1281 err.emit()
1282 } else if let Err(reported) = qself_ty.error_reported() {
1283 reported
1284 } else {
1285 self.maybe_report_similar_assoc_fn(span, qself_ty, qself)?;
1286
1287 let traits: Vec<_> =
1288 self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
1289
1290 self.report_ambiguous_assoc_ty(
1292 span,
1293 &[qself_ty.to_string()],
1294 &traits,
1295 assoc_ident.name,
1296 )
1297 };
1298 return Err(reported);
1299 }
1300 };
1301
1302 let trait_did = bound.def_id();
1303 let assoc_ty = self
1304 .probe_assoc_item(assoc_ident, ty::AssocKind::Type, hir_ref_id, span, trait_did)
1305 .expect("failed to find associated type");
1306 let ty = self.lower_assoc_ty(span, assoc_ty.def_id, assoc_segment, bound);
1307
1308 if let Some(variant_def_id) = variant_resolution {
1309 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
1310 lint.primary_message("ambiguous associated item");
1311 let mut could_refer_to = |kind: DefKind, def_id, also| {
1312 let note_msg = format!(
1313 "`{}` could{} refer to the {} defined here",
1314 assoc_ident,
1315 also,
1316 tcx.def_kind_descr(kind, def_id)
1317 );
1318 lint.span_note(tcx.def_span(def_id), note_msg);
1319 };
1320
1321 could_refer_to(DefKind::Variant, variant_def_id, "");
1322 could_refer_to(DefKind::AssocTy, assoc_ty.def_id, " also");
1323
1324 lint.span_suggestion(
1325 span,
1326 "use fully-qualified syntax",
1327 format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
1328 Applicability::MachineApplicable,
1329 );
1330 });
1331 }
1332 Ok((ty, DefKind::AssocTy, assoc_ty.def_id))
1333 }
1334
1335 fn probe_inherent_assoc_ty(
1336 &self,
1337 name: Ident,
1338 segment: &hir::PathSegment<'tcx>,
1339 adt_did: DefId,
1340 self_ty: Ty<'tcx>,
1341 block: HirId,
1342 span: Span,
1343 ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> {
1344 let tcx = self.tcx();
1345
1346 if !tcx.features().inherent_associated_types() {
1353 return Ok(None);
1354 }
1355
1356 let candidates: Vec<_> = tcx
1357 .inherent_impls(adt_did)
1358 .iter()
1359 .filter_map(|&impl_| {
1360 let (item, scope) =
1361 self.probe_assoc_item_unchecked(name, ty::AssocKind::Type, block, impl_)?;
1362 Some((impl_, (item.def_id, scope)))
1363 })
1364 .collect();
1365
1366 if candidates.is_empty() {
1367 return Ok(None);
1368 }
1369
1370 let infcx_;
1377 let infcx = match self.infcx() {
1378 Some(infcx) => infcx,
1379 None => {
1380 assert!(!self_ty.has_infer());
1381 infcx_ = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis());
1382 &infcx_
1383 }
1384 };
1385
1386 let param_env = tcx.param_env(block.owner);
1389
1390 let mut universes = if self_ty.has_escaping_bound_vars() {
1391 vec![None; self_ty.outer_exclusive_binder().as_usize()]
1392 } else {
1393 vec![]
1394 };
1395
1396 let (impl_, (assoc_item, def_scope)) = crate::traits::with_replaced_escaping_bound_vars(
1397 infcx,
1398 &mut universes,
1399 self_ty,
1400 |self_ty| {
1401 self.select_inherent_assoc_type_candidates(
1402 infcx, name, span, self_ty, param_env, candidates,
1403 )
1404 },
1405 )?;
1406
1407 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1408
1409 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1413 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1414 let args = tcx.mk_args_from_iter(
1415 std::iter::once(ty::GenericArg::from(self_ty))
1416 .chain(args.into_iter().skip(parent_args.len())),
1417 );
1418
1419 let ty =
1420 Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new_from_args(tcx, assoc_item, args));
1421
1422 Ok(Some((ty, assoc_item)))
1423 }
1424
1425 fn select_inherent_assoc_type_candidates(
1426 &self,
1427 infcx: &InferCtxt<'tcx>,
1428 name: Ident,
1429 span: Span,
1430 self_ty: Ty<'tcx>,
1431 param_env: ParamEnv<'tcx>,
1432 candidates: Vec<(DefId, (DefId, DefId))>,
1433 ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
1434 let tcx = self.tcx();
1435 let mut fulfillment_errors = Vec::new();
1436
1437 let applicable_candidates: Vec<_> = candidates
1438 .iter()
1439 .copied()
1440 .filter(|&(impl_, _)| {
1441 infcx.probe(|_| {
1442 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
1443 let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
1444
1445 let impl_args = infcx.fresh_args_for_item(span, impl_);
1446 let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1447 let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
1448
1449 if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
1451 return false;
1452 }
1453
1454 let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1456 let impl_bounds =
1457 ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
1458 let impl_obligations = traits::predicates_for_generics(
1459 |_, _| ObligationCause::dummy(),
1460 param_env,
1461 impl_bounds,
1462 );
1463 ocx.register_obligations(impl_obligations);
1464
1465 let mut errors = ocx.select_where_possible();
1466 if !errors.is_empty() {
1467 fulfillment_errors.append(&mut errors);
1468 return false;
1469 }
1470
1471 true
1472 })
1473 })
1474 .collect();
1475
1476 match &applicable_candidates[..] {
1477 &[] => Err(self.complain_about_inherent_assoc_ty_not_found(
1478 name,
1479 self_ty,
1480 candidates,
1481 fulfillment_errors,
1482 span,
1483 )),
1484
1485 &[applicable_candidate] => Ok(applicable_candidate),
1486
1487 &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc_ty(
1488 name,
1489 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1490 span,
1491 )),
1492 }
1493 }
1494
1495 fn probe_assoc_item(
1499 &self,
1500 ident: Ident,
1501 kind: ty::AssocKind,
1502 block: HirId,
1503 span: Span,
1504 scope: DefId,
1505 ) -> Option<ty::AssocItem> {
1506 let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?;
1507 self.check_assoc_item(item.def_id, ident, scope, block, span);
1508 Some(item)
1509 }
1510
1511 fn probe_assoc_item_unchecked(
1516 &self,
1517 ident: Ident,
1518 kind: ty::AssocKind,
1519 block: HirId,
1520 scope: DefId,
1521 ) -> Option<(ty::AssocItem, DefId)> {
1522 let tcx = self.tcx();
1523
1524 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1525 let item = tcx
1529 .associated_items(scope)
1530 .filter_by_name_unhygienic(ident.name)
1531 .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1532
1533 Some((*item, def_scope))
1534 }
1535
1536 fn check_assoc_item(
1538 &self,
1539 item_def_id: DefId,
1540 ident: Ident,
1541 scope: DefId,
1542 block: HirId,
1543 span: Span,
1544 ) {
1545 let tcx = self.tcx();
1546
1547 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1548 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1549 span,
1550 kind: tcx.def_descr(item_def_id),
1551 name: ident,
1552 defined_here_label: tcx.def_span(item_def_id),
1553 });
1554 }
1555
1556 tcx.check_stability(item_def_id, Some(block), span, None);
1557 }
1558
1559 fn probe_traits_that_match_assoc_ty(
1560 &self,
1561 qself_ty: Ty<'tcx>,
1562 assoc_ident: Ident,
1563 ) -> Vec<String> {
1564 let tcx = self.tcx();
1565
1566 let infcx_;
1569 let infcx = if let Some(infcx) = self.infcx() {
1570 infcx
1571 } else {
1572 assert!(!qself_ty.has_infer());
1573 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1574 &infcx_
1575 };
1576
1577 tcx.all_traits()
1578 .filter(|trait_def_id| {
1579 tcx.associated_items(*trait_def_id)
1581 .in_definition_order()
1582 .any(|i| {
1583 i.kind.namespace() == Namespace::TypeNS
1584 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1585 && matches!(i.kind, ty::AssocKind::Type)
1586 })
1587 && tcx.visibility(*trait_def_id)
1589 .is_accessible_from(self.item_def_id(), tcx)
1590 && tcx.all_impls(*trait_def_id)
1591 .any(|impl_def_id| {
1592 let impl_header = tcx.impl_trait_header(impl_def_id);
1593 impl_header.is_some_and(|header| {
1594 let trait_ref = header.trait_ref.instantiate(
1595 tcx,
1596 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1597 );
1598
1599 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1600 if value.has_escaping_bound_vars() {
1602 return false;
1603 }
1604 infcx
1605 .can_eq(
1606 ty::ParamEnv::empty(),
1607 trait_ref.self_ty(),
1608 value,
1609 ) && header.polarity != ty::ImplPolarity::Negative
1610 })
1611 })
1612 })
1613 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1614 .collect()
1615 }
1616
1617 #[instrument(level = "debug", skip_all)]
1619 fn lower_qpath(
1620 &self,
1621 span: Span,
1622 opt_self_ty: Option<Ty<'tcx>>,
1623 item_def_id: DefId,
1624 trait_segment: &hir::PathSegment<'tcx>,
1625 item_segment: &hir::PathSegment<'tcx>,
1626 ) -> Ty<'tcx> {
1627 let tcx = self.tcx();
1628
1629 let trait_def_id = tcx.parent(item_def_id);
1630 debug!(?trait_def_id);
1631
1632 let Some(self_ty) = opt_self_ty else {
1633 return self.error_missing_qpath_self_ty(trait_def_id, span, item_segment);
1634 };
1635 debug!(?self_ty);
1636
1637 let trait_ref =
1638 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
1639 debug!(?trait_ref);
1640
1641 let item_args =
1642 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1643
1644 Ty::new_projection_from_args(tcx, item_def_id, item_args)
1645 }
1646
1647 fn error_missing_qpath_self_ty(
1648 &self,
1649 trait_def_id: DefId,
1650 span: Span,
1651 item_segment: &hir::PathSegment<'tcx>,
1652 ) -> Ty<'tcx> {
1653 let tcx = self.tcx();
1654 let path_str = tcx.def_path_str(trait_def_id);
1655
1656 let def_id = self.item_def_id();
1657 debug!(item_def_id = ?def_id);
1658
1659 let parent_def_id =
1661 tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
1662 debug!(?parent_def_id);
1663
1664 let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
1667 let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
1668
1669 let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
1670 vec!["Self".to_string()]
1671 } else {
1672 tcx.all_impls(trait_def_id)
1674 .filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
1675 .filter(|header| {
1676 tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1678 && header.polarity != ty::ImplPolarity::Negative
1679 })
1680 .map(|header| header.trait_ref.instantiate_identity().self_ty())
1681 .filter(|self_ty| !self_ty.has_non_region_param())
1683 .map(|self_ty| tcx.erase_regions(self_ty).to_string())
1684 .collect()
1685 };
1686 let reported =
1690 self.report_ambiguous_assoc_ty(span, &type_names, &[path_str], item_segment.ident.name);
1691 Ty::new_error(tcx, reported)
1692 }
1693
1694 pub fn prohibit_generic_args<'a>(
1695 &self,
1696 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1697 err_extend: GenericsArgsErrExtend<'a>,
1698 ) -> Result<(), ErrorGuaranteed> {
1699 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1700 let mut result = Ok(());
1701 if let Some(_) = args_visitors.clone().next() {
1702 result = Err(self.report_prohibit_generics_error(
1703 segments.clone(),
1704 args_visitors,
1705 err_extend,
1706 ));
1707 }
1708
1709 for segment in segments {
1710 if let Some(c) = segment.args().constraints.first() {
1712 return Err(prohibit_assoc_item_constraint(self, c, None));
1713 }
1714 }
1715
1716 result
1717 }
1718
1719 pub fn probe_generic_path_segments(
1737 &self,
1738 segments: &[hir::PathSegment<'_>],
1739 self_ty: Option<Ty<'tcx>>,
1740 kind: DefKind,
1741 def_id: DefId,
1742 span: Span,
1743 ) -> Vec<GenericPathSegment> {
1744 let tcx = self.tcx();
1790
1791 assert!(!segments.is_empty());
1792 let last = segments.len() - 1;
1793
1794 let mut generic_segments = vec![];
1795
1796 match kind {
1797 DefKind::Ctor(CtorOf::Struct, ..) => {
1799 let generics = tcx.generics_of(def_id);
1802 let generics_def_id = generics.parent.unwrap_or(def_id);
1805 generic_segments.push(GenericPathSegment(generics_def_id, last));
1806 }
1807
1808 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
1810 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
1811 let adt_def = self.probe_adt(span, self_ty).unwrap();
1812 debug_assert!(adt_def.is_enum());
1813 (adt_def.did(), last)
1814 } else if last >= 1 && segments[last - 1].args.is_some() {
1815 let mut def_id = def_id;
1818
1819 if let DefKind::Ctor(..) = kind {
1821 def_id = tcx.parent(def_id);
1822 }
1823
1824 let enum_def_id = tcx.parent(def_id);
1826 (enum_def_id, last - 1)
1827 } else {
1828 let generics = tcx.generics_of(def_id);
1834 (generics.parent.unwrap_or(def_id), last)
1837 };
1838 generic_segments.push(GenericPathSegment(generics_def_id, index));
1839 }
1840
1841 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
1843 generic_segments.push(GenericPathSegment(def_id, last));
1844 }
1845
1846 DefKind::AssocFn | DefKind::AssocConst => {
1848 if segments.len() >= 2 {
1849 let generics = tcx.generics_of(def_id);
1850 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
1851 }
1852 generic_segments.push(GenericPathSegment(def_id, last));
1853 }
1854
1855 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
1856 }
1857
1858 debug!(?generic_segments);
1859
1860 generic_segments
1861 }
1862
1863 #[instrument(level = "debug", skip_all)]
1865 pub fn lower_path(
1866 &self,
1867 opt_self_ty: Option<Ty<'tcx>>,
1868 path: &hir::Path<'tcx>,
1869 hir_id: HirId,
1870 permit_variants: bool,
1871 ) -> Ty<'tcx> {
1872 debug!(?path.res, ?opt_self_ty, ?path.segments);
1873 let tcx = self.tcx();
1874
1875 let span = path.span;
1876 match path.res {
1877 Res::Def(DefKind::OpaqueTy, did) => {
1878 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
1880 let item_segment = path.segments.split_last().unwrap();
1881 let _ = self
1882 .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy);
1883 let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0);
1884 Ty::new_opaque(tcx, did, args)
1885 }
1886 Res::Def(
1887 DefKind::Enum
1888 | DefKind::TyAlias
1889 | DefKind::Struct
1890 | DefKind::Union
1891 | DefKind::ForeignTy,
1892 did,
1893 ) => {
1894 assert_eq!(opt_self_ty, None);
1895 let _ = self.prohibit_generic_args(
1896 path.segments.split_last().unwrap().1.iter(),
1897 GenericsArgsErrExtend::None,
1898 );
1899 self.lower_path_segment(span, did, path.segments.last().unwrap())
1900 }
1901 Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
1902 assert_eq!(opt_self_ty, None);
1905
1906 let generic_segments =
1907 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
1908 let indices: FxHashSet<_> =
1909 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
1910 let _ = self.prohibit_generic_args(
1911 path.segments.iter().enumerate().filter_map(|(index, seg)| {
1912 if !indices.contains(&index) { Some(seg) } else { None }
1913 }),
1914 GenericsArgsErrExtend::DefVariant(&path.segments),
1915 );
1916
1917 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
1918 self.lower_path_segment(span, *def_id, &path.segments[*index])
1919 }
1920 Res::Def(DefKind::TyParam, def_id) => {
1921 assert_eq!(opt_self_ty, None);
1922 let _ = self.prohibit_generic_args(
1923 path.segments.iter(),
1924 GenericsArgsErrExtend::Param(def_id),
1925 );
1926 self.lower_ty_param(hir_id)
1927 }
1928 Res::SelfTyParam { .. } => {
1929 assert_eq!(opt_self_ty, None);
1931 let _ = self.prohibit_generic_args(
1932 path.segments.iter(),
1933 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
1934 GenericsArgsErrExtend::SelfTyParam(
1935 ident.span.shrink_to_hi().to(args.span_ext),
1936 )
1937 } else {
1938 GenericsArgsErrExtend::None
1939 },
1940 );
1941 tcx.types.self_param
1942 }
1943 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
1944 assert_eq!(opt_self_ty, None);
1946 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
1948 let _ = self.prohibit_generic_args(
1949 path.segments.iter(),
1950 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
1951 );
1952 if forbid_generic && ty.has_param() {
1972 let mut err = self.dcx().struct_span_err(
1973 path.span,
1974 "generic `Self` types are currently not permitted in anonymous constants",
1975 );
1976 if let Some(hir::Node::Item(&hir::Item {
1977 kind: hir::ItemKind::Impl(impl_),
1978 ..
1979 })) = tcx.hir().get_if_local(def_id)
1980 {
1981 err.span_note(impl_.self_ty.span, "not a concrete type");
1982 }
1983 let reported = err.emit();
1984 Ty::new_error(tcx, reported)
1985 } else {
1986 ty
1987 }
1988 }
1989 Res::Def(DefKind::AssocTy, def_id) => {
1990 debug_assert!(path.segments.len() >= 2);
1991 let _ = self.prohibit_generic_args(
1992 path.segments[..path.segments.len() - 2].iter(),
1993 GenericsArgsErrExtend::None,
1994 );
1995 self.lower_qpath(
1996 span,
1997 opt_self_ty,
1998 def_id,
1999 &path.segments[path.segments.len() - 2],
2000 path.segments.last().unwrap(),
2001 )
2002 }
2003 Res::PrimTy(prim_ty) => {
2004 assert_eq!(opt_self_ty, None);
2005 let _ = self.prohibit_generic_args(
2006 path.segments.iter(),
2007 GenericsArgsErrExtend::PrimTy(prim_ty),
2008 );
2009 match prim_ty {
2010 hir::PrimTy::Bool => tcx.types.bool,
2011 hir::PrimTy::Char => tcx.types.char,
2012 hir::PrimTy::Int(it) => Ty::new_int(tcx, ty::int_ty(it)),
2013 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, ty::uint_ty(uit)),
2014 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ty::float_ty(ft)),
2015 hir::PrimTy::Str => tcx.types.str_,
2016 }
2017 }
2018 Res::Err => {
2019 let e = self
2020 .tcx()
2021 .dcx()
2022 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2023 Ty::new_error(tcx, e)
2024 }
2025 Res::Def(..) => {
2026 assert_eq!(
2027 path.segments.get(0).map(|seg| seg.ident.name),
2028 Some(kw::SelfUpper),
2029 "only expected incorrect resolution for `Self`"
2030 );
2031 Ty::new_error(
2032 self.tcx(),
2033 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2034 )
2035 }
2036 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2037 }
2038 }
2039
2040 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2045 let tcx = self.tcx();
2046 match tcx.named_bound_var(hir_id) {
2047 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2048 let name = tcx.item_name(def_id.to_def_id());
2049 let br = ty::BoundTy {
2050 var: ty::BoundVar::from_u32(index),
2051 kind: ty::BoundTyKind::Param(def_id.to_def_id(), name),
2052 };
2053 Ty::new_bound(tcx, debruijn, br)
2054 }
2055 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2056 let item_def_id = tcx.hir().ty_param_owner(def_id);
2057 let generics = tcx.generics_of(item_def_id);
2058 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2059 Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id))
2060 }
2061 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2062 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2063 }
2064 }
2065
2066 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2071 let tcx = self.tcx();
2072
2073 match tcx.named_bound_var(path_hir_id) {
2074 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2075 let item_def_id = tcx.parent(param_def_id);
2078 let generics = tcx.generics_of(item_def_id);
2079 let index = generics.param_def_id_to_index[¶m_def_id];
2080 let name = tcx.item_name(param_def_id);
2081 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2082 }
2083 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2084 ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
2085 }
2086 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2087 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2088 }
2089 }
2090
2091 #[instrument(skip(self), level = "debug")]
2093 pub fn lower_const_arg(
2094 &self,
2095 const_arg: &hir::ConstArg<'tcx>,
2096 feed: FeedConstTy,
2097 ) -> Const<'tcx> {
2098 let tcx = self.tcx();
2099
2100 if let FeedConstTy::Param(param_def_id) = feed
2101 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2102 {
2103 tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
2104 }
2105
2106 let hir_id = const_arg.hir_id;
2107 match const_arg.kind {
2108 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2109 debug!(?maybe_qself, ?path);
2110 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2111 self.lower_const_path_resolved(opt_self_ty, path, hir_id)
2112 }
2113 hir::ConstArgKind::Path(qpath) => ty::Const::new_error_with_message(
2114 tcx,
2115 qpath.span(),
2116 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
2117 ),
2118 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2119 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2120 }
2121 }
2122
2123 fn lower_const_path_resolved(
2124 &self,
2125 opt_self_ty: Option<Ty<'tcx>>,
2126 path: &hir::Path<'tcx>,
2127 hir_id: HirId,
2128 ) -> Const<'tcx> {
2129 let tcx = self.tcx();
2130 let span = path.span;
2131 match path.res {
2132 Res::Def(DefKind::ConstParam, def_id) => {
2133 assert_eq!(opt_self_ty, None);
2134 let _ = self.prohibit_generic_args(
2135 path.segments.iter(),
2136 GenericsArgsErrExtend::Param(def_id),
2137 );
2138 self.lower_const_param(def_id, hir_id)
2139 }
2140 Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2141 assert_eq!(opt_self_ty, None);
2142 let _ = self.prohibit_generic_args(
2143 path.segments.split_last().unwrap().1.iter(),
2144 GenericsArgsErrExtend::None,
2145 );
2146 let args = self.lower_generic_args_of_path_segment(
2147 span,
2148 did,
2149 path.segments.last().unwrap(),
2150 );
2151 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2152 }
2153 Res::Def(DefKind::Static { .. }, _) => {
2154 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2155 }
2156 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2158 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2159 let args = self.lower_generic_args_of_path_segment(
2160 span,
2161 did,
2162 path.segments.last().unwrap(),
2163 );
2164 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2165 }
2166
2167 Res::Def(
2170 DefKind::Mod
2171 | DefKind::Enum
2172 | DefKind::Variant
2173 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2174 | DefKind::Struct
2175 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2176 | DefKind::OpaqueTy
2177 | DefKind::TyAlias
2178 | DefKind::TraitAlias
2179 | DefKind::AssocTy
2180 | DefKind::Union
2181 | DefKind::Trait
2182 | DefKind::ForeignTy
2183 | DefKind::AssocConst
2184 | DefKind::TyParam
2185 | DefKind::Macro(_)
2186 | DefKind::LifetimeParam
2187 | DefKind::Use
2188 | DefKind::ForeignMod
2189 | DefKind::AnonConst
2190 | DefKind::InlineConst
2191 | DefKind::Field
2192 | DefKind::Impl { .. }
2193 | DefKind::Closure
2194 | DefKind::ExternCrate
2195 | DefKind::GlobalAsm
2196 | DefKind::SyntheticCoroutineBody,
2197 _,
2198 )
2199 | Res::PrimTy(_)
2200 | Res::SelfTyParam { .. }
2201 | Res::SelfTyAlias { .. }
2202 | Res::SelfCtor(_)
2203 | Res::Local(_)
2204 | Res::ToolMod
2205 | Res::NonMacroAttr(_)
2206 | Res::Err => Const::new_error_with_message(tcx, span, "invalid Res for const path"),
2207 }
2208 }
2209
2210 #[instrument(skip(self), level = "debug")]
2213 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2214 let tcx = self.tcx();
2215
2216 let expr = &tcx.hir().body(anon.body).value;
2217 debug!(?expr);
2218
2219 let ty = tcx
2220 .type_of(anon.def_id)
2221 .no_bound_vars()
2222 .expect("const parameter types cannot be generic");
2223
2224 match self.try_lower_anon_const_lit(ty, expr) {
2225 Some(v) => v,
2226 None => ty::Const::new_unevaluated(
2227 tcx,
2228 ty::UnevaluatedConst {
2229 def: anon.def_id.to_def_id(),
2230 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2231 },
2232 ),
2233 }
2234 }
2235
2236 #[instrument(skip(self), level = "debug")]
2237 fn try_lower_anon_const_lit(
2238 &self,
2239 ty: Ty<'tcx>,
2240 expr: &'tcx hir::Expr<'tcx>,
2241 ) -> Option<Const<'tcx>> {
2242 let tcx = self.tcx();
2243
2244 let expr = match &expr.kind {
2247 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2248 block.expr.as_ref().unwrap()
2249 }
2250 _ => expr,
2251 };
2252
2253 if let hir::ExprKind::Path(hir::QPath::Resolved(
2254 _,
2255 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2256 )) = expr.kind
2257 {
2258 span_bug!(
2259 expr.span,
2260 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2261 );
2262 };
2263
2264 let lit_input = match expr.kind {
2265 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
2266 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2267 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
2268 _ => None,
2269 },
2270 _ => None,
2271 };
2272
2273 lit_input
2274 .filter(|l| !l.ty.has_aliases())
2277 .map(|l| tcx.at(expr.span).lit_to_const(l))
2278 }
2279
2280 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2281 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2282 match idx {
2283 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2284 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2285 }
2286 }
2287
2288 #[instrument(level = "debug", skip(self), ret)]
2290 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2291 let tcx = self.tcx();
2292
2293 let result_ty = match &hir_ty.kind {
2294 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2295 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2296 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2297 hir::TyKind::Ref(region, mt) => {
2298 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2299 debug!(?r);
2300 let t = self.lower_ty(mt.ty);
2301 Ty::new_ref(tcx, r, t, mt.mutbl)
2302 }
2303 hir::TyKind::Never => tcx.types.never,
2304 hir::TyKind::Tup(fields) => {
2305 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2306 }
2307 hir::TyKind::BareFn(bf) => {
2308 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span);
2309
2310 Ty::new_fn_ptr(
2311 tcx,
2312 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2313 )
2314 }
2315 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2316 tcx,
2317 ty::Binder::bind_with_vars(
2318 self.lower_ty(binder.inner_ty),
2319 tcx.late_bound_vars(hir_ty.hir_id),
2320 ),
2321 ),
2322 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2323 let lifetime = tagged_ptr.pointer();
2324 let repr = tagged_ptr.tag();
2325
2326 if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2327 Ty::new_error(tcx, guar)
2331 } else {
2332 let repr = match repr {
2333 TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2334 TraitObjectSyntax::DynStar => ty::DynStar,
2335 };
2336 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2337 }
2338 }
2339 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2343 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2344 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2345 }) =>
2346 {
2347 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2348 Ty::new_error(tcx, guar)
2349 }
2350 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2351 debug!(?maybe_qself, ?path);
2352 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2353 self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
2354 }
2355 &hir::TyKind::OpaqueDef(opaque_ty) => {
2356 let in_trait = match opaque_ty.origin {
2360 hir::OpaqueTyOrigin::FnReturn {
2361 in_trait_or_impl: Some(hir::RpitContext::Trait),
2362 ..
2363 }
2364 | hir::OpaqueTyOrigin::AsyncFn {
2365 in_trait_or_impl: Some(hir::RpitContext::Trait),
2366 ..
2367 } => true,
2368 hir::OpaqueTyOrigin::FnReturn {
2369 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2370 ..
2371 }
2372 | hir::OpaqueTyOrigin::AsyncFn {
2373 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2374 ..
2375 }
2376 | hir::OpaqueTyOrigin::TyAlias { .. } => false,
2377 };
2378
2379 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2380 }
2381 hir::TyKind::TraitAscription(hir_bounds) => {
2382 let self_ty = self.ty_infer(None, hir_ty.span);
2385 let mut bounds = Bounds::default();
2386 self.lower_bounds(
2387 self_ty,
2388 hir_bounds.iter(),
2389 &mut bounds,
2390 ty::List::empty(),
2391 PredicateFilter::All,
2392 );
2393 self.register_trait_ascription_bounds(
2394 bounds.clauses().collect(),
2395 hir_ty.hir_id,
2396 hir_ty.span,
2397 );
2398 self_ty
2399 }
2400 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2404 if segment.args.is_some_and(|args| {
2405 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2406 }) =>
2407 {
2408 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2409 Ty::new_error(tcx, guar)
2410 }
2411 hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
2412 debug!(?qself, ?segment);
2413 let ty = self.lower_ty(qself);
2414 self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
2415 .map(|(ty, _, _)| ty)
2416 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2417 }
2418 &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
2419 let def_id = tcx.require_lang_item(lang_item, Some(span));
2420 let (args, _) = self.lower_generic_args_of_path(
2421 span,
2422 def_id,
2423 &[],
2424 &hir::PathSegment::invalid(),
2425 None,
2426 );
2427 tcx.at(span).type_of(def_id).instantiate(tcx, args)
2428 }
2429 hir::TyKind::Array(ty, length) => {
2430 let length = self.lower_const_arg(length, FeedConstTy::No);
2431 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2432 }
2433 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2434 hir::TyKind::Infer(()) => {
2435 self.ty_infer(None, hir_ty.span)
2440 }
2441 hir::TyKind::Pat(ty, pat) => {
2442 let ty_span = ty.span;
2443 let ty = self.lower_ty(ty);
2444 let pat_ty = match pat.kind {
2445 hir::TyPatKind::Range(start, end, include_end) => {
2446 let ty = match ty.kind() {
2447 ty::Int(_) | ty::Uint(_) | ty::Char => ty,
2448 _ => Ty::new_error(
2449 tcx,
2450 self.dcx().emit_err(InvalidBaseType {
2451 ty,
2452 pat: "range",
2453 ty_span,
2454 pat_span: pat.span,
2455 }),
2456 ),
2457 };
2458 let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
2459 let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
2460
2461 let include_end = match include_end {
2462 hir::RangeEnd::Included => true,
2463 hir::RangeEnd::Excluded => false,
2464 };
2465
2466 let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
2467 Ty::new_pat(tcx, ty, pat)
2468 }
2469 hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
2470 };
2471 self.record_ty(pat.hir_id, ty, pat.span);
2472 pat_ty
2473 }
2474 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2475 };
2476
2477 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2478 result_ty
2479 }
2480
2481 #[instrument(level = "debug", skip(self), ret)]
2483 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
2484 let tcx = self.tcx();
2485
2486 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2487 debug!(?lifetimes);
2488
2489 let def_id = if in_trait {
2493 tcx.associated_type_for_impl_trait_in_trait(def_id).to_def_id()
2494 } else {
2495 def_id.to_def_id()
2496 };
2497
2498 let generics = tcx.generics_of(def_id);
2499 debug!(?generics);
2500
2501 let offset = generics.count() - lifetimes.len();
2505
2506 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2507 if let Some(i) = (param.index as usize).checked_sub(offset) {
2508 let (lifetime, _) = lifetimes[i];
2509 self.lower_resolved_lifetime(lifetime).into()
2510 } else {
2511 tcx.mk_param_from_def(param)
2512 }
2513 });
2514 debug!(?args);
2515
2516 if in_trait {
2517 Ty::new_projection_from_args(tcx, def_id, args)
2518 } else {
2519 Ty::new_opaque(tcx, def_id, args)
2520 }
2521 }
2522
2523 pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
2524 match ty.kind {
2525 hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => {
2526 self.record_ty(ty.hir_id, expected_ty, ty.span);
2527 expected_ty
2528 }
2529 _ => self.lower_ty(ty),
2530 }
2531 }
2532
2533 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2535 pub fn lower_fn_ty(
2536 &self,
2537 hir_id: HirId,
2538 safety: hir::Safety,
2539 abi: rustc_abi::ExternAbi,
2540 decl: &hir::FnDecl<'tcx>,
2541 generics: Option<&hir::Generics<'_>>,
2542 hir_ty: Option<&hir::Ty<'_>>,
2543 ) -> ty::PolyFnSig<'tcx> {
2544 let tcx = self.tcx();
2545 let bound_vars = tcx.late_bound_vars(hir_id);
2546 debug!(?bound_vars);
2547
2548 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2549
2550 debug!(?output_ty);
2551
2552 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2553 let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2554
2555 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2556 tcx.hir_node(hir_id)
2557 {
2558 check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2559 }
2560
2561 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
2563
2564 if !bare_fn_ty.references_error() {
2565 let inputs = bare_fn_ty.inputs();
2572 let late_bound_in_args =
2573 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2574 let output = bare_fn_ty.output();
2575 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2576
2577 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2578 struct_span_code_err!(
2579 self.dcx(),
2580 decl.output.span(),
2581 E0581,
2582 "return type references {}, which is not constrained by the fn input types",
2583 br_name
2584 )
2585 });
2586 }
2587
2588 bare_fn_ty
2589 }
2590
2591 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2596 &self,
2597 fn_hir_id: HirId,
2598 arg_idx: Option<usize>,
2599 ) -> Option<Ty<'tcx>> {
2600 let tcx = self.tcx();
2601 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2602 tcx.hir_node(fn_hir_id)
2603 else {
2604 return None;
2605 };
2606 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2607
2608 let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
2609
2610 let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
2611 tcx,
2612 *ident,
2613 ty::AssocKind::Fn,
2614 trait_ref.def_id,
2615 )?;
2616
2617 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2618 tcx,
2619 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2620 );
2621 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2622
2623 Some(if let Some(arg_idx) = arg_idx {
2624 *fn_sig.inputs().get(arg_idx)?
2625 } else {
2626 fn_sig.output()
2627 })
2628 }
2629
2630 #[instrument(level = "trace", skip(self, generate_err))]
2631 fn validate_late_bound_regions<'cx>(
2632 &'cx self,
2633 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2634 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2635 generate_err: impl Fn(&str) -> Diag<'cx>,
2636 ) {
2637 for br in referenced_regions.difference(&constrained_regions) {
2638 let br_name = match *br {
2639 ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2640 | ty::BoundRegionKind::Anon
2641 | ty::BoundRegionKind::ClosureEnv => "an anonymous lifetime".to_string(),
2642 ty::BoundRegionKind::Named(_, name) => format!("lifetime `{name}`"),
2643 };
2644
2645 let mut err = generate_err(&br_name);
2646
2647 if let ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2648 | ty::BoundRegionKind::Anon = *br
2649 {
2650 err.note(
2657 "lifetimes appearing in an associated or opaque type are not considered constrained",
2658 );
2659 err.note("consider introducing a named lifetime parameter");
2660 }
2661
2662 err.emit();
2663 }
2664 }
2665
2666 #[instrument(level = "debug", skip(self, span), ret)]
2674 fn compute_object_lifetime_bound(
2675 &self,
2676 span: Span,
2677 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2678 ) -> Option<ty::Region<'tcx>> {
2680 let tcx = self.tcx();
2681
2682 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2685
2686 if derived_region_bounds.is_empty() {
2689 return None;
2690 }
2691
2692 if derived_region_bounds.iter().any(|r| r.is_static()) {
2695 return Some(tcx.lifetimes.re_static);
2696 }
2697
2698 let r = derived_region_bounds[0];
2702 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2703 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2704 }
2705 Some(r)
2706 }
2707}