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