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