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, ObligationCause};
37use rustc_middle::middle::stability::AllowUnstable;
38use rustc_middle::mir::interpret::LitToConstInput;
39use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
40use rustc_middle::ty::{
41 self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
42 TypeVisitableExt, TypingMode, Upcast, fold_regions,
43};
44use rustc_middle::{bug, span_bug};
45use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
46use rustc_session::parse::feature_err;
47use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
48use rustc_trait_selection::infer::InferCtxtExt;
49use rustc_trait_selection::traits::wf::object_region_bounds;
50use rustc_trait_selection::traits::{self, ObligationCtxt};
51use tracing::{debug, instrument};
52
53use crate::check::check_abi_fn_ptr;
54use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation};
55use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
56use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
57use crate::middle::resolve_bound_vars as rbv;
58use crate::require_c_abi_if_c_variadic;
59
60#[derive(Debug)]
62pub struct GenericPathSegment(pub DefId, pub usize);
63
64#[derive(Copy, Clone, Debug)]
65pub enum PredicateFilter {
66 All,
68
69 SelfOnly,
71
72 SelfTraitThatDefines(Ident),
76
77 SelfAndAssociatedTypeBounds,
81
82 ConstIfConst,
84
85 SelfConstIfConst,
87}
88
89#[derive(Debug)]
90pub enum RegionInferReason<'a> {
91 ExplicitObjectLifetime,
93 ObjectLifetimeDefault,
95 Param(&'a ty::GenericParamDef),
97 RegionPredicate,
98 Reference,
99 OutlivesBound,
100}
101
102pub trait HirTyLowerer<'tcx> {
107 fn tcx(&self) -> TyCtxt<'tcx>;
108
109 fn dcx(&self) -> DiagCtxtHandle<'_>;
110
111 fn item_def_id(&self) -> LocalDefId;
113
114 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
116
117 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
119
120 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
122
123 fn register_trait_ascription_bounds(
124 &self,
125 bounds: Vec<(ty::Clause<'tcx>, Span)>,
126 hir_id: HirId,
127 span: Span,
128 );
129
130 fn probe_ty_param_bounds(
145 &self,
146 span: Span,
147 def_id: LocalDefId,
148 assoc_ident: Ident,
149 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
150
151 fn lower_assoc_item_path(
164 &self,
165 span: Span,
166 item_def_id: DefId,
167 item_segment: &hir::PathSegment<'tcx>,
168 poly_trait_ref: ty::PolyTraitRef<'tcx>,
169 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
170
171 fn lower_fn_sig(
172 &self,
173 decl: &hir::FnDecl<'tcx>,
174 generics: Option<&hir::Generics<'_>>,
175 hir_id: HirId,
176 hir_ty: Option<&hir::Ty<'_>>,
177 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
178
179 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
186
187 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
189
190 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
192
193 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
198 where
199 Self: Sized,
200 {
201 self
202 }
203
204 fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation>;
207}
208
209enum AssocItemQSelf {
213 Trait(DefId),
214 TyParam(LocalDefId, Span),
215 SelfTyAlias,
216}
217
218impl AssocItemQSelf {
219 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
220 match *self {
221 Self::Trait(def_id) => tcx.def_path_str(def_id),
222 Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
223 Self::SelfTyAlias => kw::SelfUpper.to_string(),
224 }
225 }
226}
227
228#[derive(Debug, Clone, Copy)]
235pub enum FeedConstTy<'a, 'tcx> {
236 Param(DefId, &'a [ty::GenericArg<'tcx>]),
244 No,
246}
247
248#[derive(Debug, Clone, Copy)]
249enum LowerTypeRelativePathMode {
250 Type(PermitVariants),
251 Const,
252}
253
254impl LowerTypeRelativePathMode {
255 fn assoc_tag(self) -> ty::AssocTag {
256 match self {
257 Self::Type(_) => ty::AssocTag::Type,
258 Self::Const => ty::AssocTag::Const,
259 }
260 }
261
262 fn def_kind(self) -> DefKind {
263 match self {
264 Self::Type(_) => DefKind::AssocTy,
265 Self::Const => DefKind::AssocConst,
266 }
267 }
268
269 fn permit_variants(self) -> PermitVariants {
270 match self {
271 Self::Type(permit_variants) => permit_variants,
272 Self::Const => PermitVariants::No,
275 }
276 }
277}
278
279#[derive(Debug, Clone, Copy)]
281pub enum PermitVariants {
282 Yes,
283 No,
284}
285
286#[derive(Debug, Clone, Copy)]
287enum TypeRelativePath<'tcx> {
288 AssocItem(DefId, GenericArgsRef<'tcx>),
289 Variant { adt: Ty<'tcx>, variant_did: DefId },
290}
291
292#[derive(Copy, Clone, PartialEq, Debug)]
302pub enum ExplicitLateBound {
303 Yes,
304 No,
305}
306
307#[derive(Copy, Clone, PartialEq)]
308pub enum IsMethodCall {
309 Yes,
310 No,
311}
312
313#[derive(Copy, Clone, PartialEq)]
316pub(crate) enum GenericArgPosition {
317 Type,
318 Value, MethodCall,
320}
321
322#[derive(Clone, Debug)]
325pub struct GenericArgCountMismatch {
326 pub reported: ErrorGuaranteed,
327 pub invalid_args: Vec<usize>,
329}
330
331#[derive(Clone, Debug)]
334pub struct GenericArgCountResult {
335 pub explicit_late_bound: ExplicitLateBound,
336 pub correct: Result<(), GenericArgCountMismatch>,
337}
338
339pub trait GenericArgsLowerer<'a, 'tcx> {
344 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
345
346 fn provided_kind(
347 &mut self,
348 preceding_args: &[ty::GenericArg<'tcx>],
349 param: &ty::GenericParamDef,
350 arg: &GenericArg<'tcx>,
351 ) -> ty::GenericArg<'tcx>;
352
353 fn inferred_kind(
354 &mut self,
355 preceding_args: &[ty::GenericArg<'tcx>],
356 param: &ty::GenericParamDef,
357 infer_args: bool,
358 ) -> ty::GenericArg<'tcx>;
359}
360
361impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
362 #[instrument(level = "debug", skip(self), ret)]
364 pub fn lower_lifetime(
365 &self,
366 lifetime: &hir::Lifetime,
367 reason: RegionInferReason<'_>,
368 ) -> ty::Region<'tcx> {
369 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
370 self.lower_resolved_lifetime(resolved)
371 } else {
372 self.re_infer(lifetime.ident.span, reason)
373 }
374 }
375
376 #[instrument(level = "debug", skip(self), ret)]
378 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
379 let tcx = self.tcx();
380 let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id));
381
382 match resolved {
383 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
384
385 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
386 let name = lifetime_name(def_id);
387 let br = ty::BoundRegion {
388 var: ty::BoundVar::from_u32(index),
389 kind: ty::BoundRegionKind::Named(def_id.to_def_id(), name),
390 };
391 ty::Region::new_bound(tcx, debruijn, br)
392 }
393
394 rbv::ResolvedArg::EarlyBound(def_id) => {
395 let name = tcx.hir_ty_param_name(def_id);
396 let item_def_id = tcx.hir_ty_param_owner(def_id);
397 let generics = tcx.generics_of(item_def_id);
398 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
399 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
400 }
401
402 rbv::ResolvedArg::Free(scope, id) => {
403 let name = lifetime_name(id);
404 ty::Region::new_late_param(
405 tcx,
406 scope.to_def_id(),
407 ty::LateParamRegionKind::Named(id.to_def_id(), name),
408 )
409
410 }
412
413 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
414 }
415 }
416
417 pub fn lower_generic_args_of_path_segment(
418 &self,
419 span: Span,
420 def_id: DefId,
421 item_segment: &hir::PathSegment<'tcx>,
422 ) -> GenericArgsRef<'tcx> {
423 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
424 if let Some(c) = item_segment.args().constraints.first() {
425 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
426 }
427 args
428 }
429
430 #[instrument(level = "debug", skip(self, span), ret)]
465 fn lower_generic_args_of_path(
466 &self,
467 span: Span,
468 def_id: DefId,
469 parent_args: &[ty::GenericArg<'tcx>],
470 segment: &hir::PathSegment<'tcx>,
471 self_ty: Option<Ty<'tcx>>,
472 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
473 let tcx = self.tcx();
478 let generics = tcx.generics_of(def_id);
479 debug!(?generics);
480
481 if generics.has_self {
482 if generics.parent.is_some() {
483 assert!(!parent_args.is_empty())
486 } else {
487 assert!(self_ty.is_some());
489 }
490 } else {
491 assert!(self_ty.is_none());
492 }
493
494 let arg_count = check_generic_arg_count(
495 self,
496 def_id,
497 segment,
498 generics,
499 GenericArgPosition::Type,
500 self_ty.is_some(),
501 );
502
503 if generics.is_own_empty() {
508 return (tcx.mk_args(parent_args), arg_count);
509 }
510
511 struct GenericArgsCtxt<'a, 'tcx> {
512 lowerer: &'a dyn HirTyLowerer<'tcx>,
513 def_id: DefId,
514 generic_args: &'a GenericArgs<'tcx>,
515 span: Span,
516 infer_args: bool,
517 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
518 }
519
520 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
521 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
522 if did == self.def_id {
523 (Some(self.generic_args), self.infer_args)
524 } else {
525 (None, false)
527 }
528 }
529
530 fn provided_kind(
531 &mut self,
532 preceding_args: &[ty::GenericArg<'tcx>],
533 param: &ty::GenericParamDef,
534 arg: &GenericArg<'tcx>,
535 ) -> ty::GenericArg<'tcx> {
536 let tcx = self.lowerer.tcx();
537
538 if let Err(incorrect) = self.incorrect_args {
539 if incorrect.invalid_args.contains(&(param.index as usize)) {
540 return param.to_error(tcx);
541 }
542 }
543
544 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
545 if has_default {
546 tcx.check_optional_stability(
547 param.def_id,
548 Some(arg.hir_id()),
549 arg.span(),
550 None,
551 AllowUnstable::No,
552 |_, _| {
553 },
559 );
560 }
561 self.lowerer.lower_ty(ty).into()
562 };
563
564 match (¶m.kind, arg) {
565 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
566 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
567 }
568 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
569 handle_ty_args(has_default, ty.as_unambig_ty())
571 }
572 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
573 handle_ty_args(has_default, &inf.to_ty())
574 }
575 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
576 .lowerer
577 .lower_const_arg(
579 ct.as_unambig_ct(),
580 FeedConstTy::Param(param.def_id, preceding_args),
581 )
582 .into(),
583 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
584 self.lowerer.ct_infer(Some(param), inf.span).into()
585 }
586 (kind, arg) => span_bug!(
587 self.span,
588 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
589 ),
590 }
591 }
592
593 fn inferred_kind(
594 &mut self,
595 preceding_args: &[ty::GenericArg<'tcx>],
596 param: &ty::GenericParamDef,
597 infer_args: bool,
598 ) -> ty::GenericArg<'tcx> {
599 let tcx = self.lowerer.tcx();
600
601 if let Err(incorrect) = self.incorrect_args {
602 if incorrect.invalid_args.contains(&(param.index as usize)) {
603 return param.to_error(tcx);
604 }
605 }
606 match param.kind {
607 GenericParamDefKind::Lifetime => {
608 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
609 }
610 GenericParamDefKind::Type { has_default, .. } => {
611 if !infer_args && has_default {
612 if let Some(prev) =
614 preceding_args.iter().find_map(|arg| match arg.kind() {
615 GenericArgKind::Type(ty) => ty.error_reported().err(),
616 _ => None,
617 })
618 {
619 return Ty::new_error(tcx, prev).into();
621 }
622 tcx.at(self.span)
623 .type_of(param.def_id)
624 .instantiate(tcx, preceding_args)
625 .into()
626 } else if infer_args {
627 self.lowerer.ty_infer(Some(param), self.span).into()
628 } else {
629 Ty::new_misc_error(tcx).into()
631 }
632 }
633 GenericParamDefKind::Const { has_default, .. } => {
634 let ty = tcx
635 .at(self.span)
636 .type_of(param.def_id)
637 .instantiate(tcx, preceding_args);
638 if let Err(guar) = ty.error_reported() {
639 return ty::Const::new_error(tcx, guar).into();
640 }
641 if !infer_args && has_default {
642 tcx.const_param_default(param.def_id)
643 .instantiate(tcx, preceding_args)
644 .into()
645 } else if infer_args {
646 self.lowerer.ct_infer(Some(param), self.span).into()
647 } else {
648 ty::Const::new_misc_error(tcx).into()
650 }
651 }
652 }
653 }
654 }
655
656 let mut args_ctx = GenericArgsCtxt {
657 lowerer: self,
658 def_id,
659 span,
660 generic_args: segment.args(),
661 infer_args: segment.infer_args,
662 incorrect_args: &arg_count.correct,
663 };
664 let args = lower_generic_args(
665 self,
666 def_id,
667 parent_args,
668 self_ty.is_some(),
669 self_ty,
670 &arg_count,
671 &mut args_ctx,
672 );
673
674 (args, arg_count)
675 }
676
677 #[instrument(level = "debug", skip(self))]
678 pub fn lower_generic_args_of_assoc_item(
679 &self,
680 span: Span,
681 item_def_id: DefId,
682 item_segment: &hir::PathSegment<'tcx>,
683 parent_args: GenericArgsRef<'tcx>,
684 ) -> GenericArgsRef<'tcx> {
685 let (args, _) =
686 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
687 if let Some(c) = item_segment.args().constraints.first() {
688 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
689 }
690 args
691 }
692
693 pub fn lower_impl_trait_ref(
697 &self,
698 trait_ref: &hir::TraitRef<'tcx>,
699 self_ty: Ty<'tcx>,
700 ) -> ty::TraitRef<'tcx> {
701 let _ = self.prohibit_generic_args(
702 trait_ref.path.segments.split_last().unwrap().1.iter(),
703 GenericsArgsErrExtend::None,
704 );
705
706 self.lower_mono_trait_ref(
707 trait_ref.path.span,
708 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
709 self_ty,
710 trait_ref.path.segments.last().unwrap(),
711 true,
712 )
713 }
714
715 #[instrument(level = "debug", skip(self, span, constness, bounds))]
739 pub(crate) fn lower_poly_trait_ref(
740 &self,
741 trait_ref: &hir::TraitRef<'tcx>,
742 span: Span,
743 constness: hir::BoundConstness,
744 polarity: hir::BoundPolarity,
745 self_ty: Ty<'tcx>,
746 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
747 predicate_filter: PredicateFilter,
748 ) -> GenericArgCountResult {
749 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
750 let trait_segment = trait_ref.path.segments.last().unwrap();
751
752 let _ = self.prohibit_generic_args(
753 trait_ref.path.segments.split_last().unwrap().1.iter(),
754 GenericsArgsErrExtend::None,
755 );
756 self.report_internal_fn_trait(span, trait_def_id, trait_segment, false);
757
758 let (generic_args, arg_count) = self.lower_generic_args_of_path(
759 trait_ref.path.span,
760 trait_def_id,
761 &[],
762 trait_segment,
763 Some(self_ty),
764 );
765
766 let tcx = self.tcx();
767 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
768 debug!(?bound_vars);
769
770 let poly_trait_ref = ty::Binder::bind_with_vars(
771 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
772 bound_vars,
773 );
774
775 debug!(?poly_trait_ref);
776
777 let polarity = match polarity {
778 rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
779 rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
780 rustc_ast::BoundPolarity::Maybe(_) => {
781 for constraint in trait_segment.args().constraints {
784 let _ = self.lower_assoc_item_constraint(
785 trait_ref.hir_ref_id,
786 poly_trait_ref,
787 constraint,
788 &mut Default::default(),
789 &mut Default::default(),
790 constraint.span,
791 predicate_filter,
792 );
793 }
794 return arg_count;
795 }
796 };
797
798 match predicate_filter {
800 PredicateFilter::All
801 | PredicateFilter::SelfOnly
802 | PredicateFilter::SelfTraitThatDefines(..)
803 | PredicateFilter::SelfAndAssociatedTypeBounds => {
804 let bound = poly_trait_ref.map_bound(|trait_ref| {
805 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
806 });
807 let bound = (bound.upcast(tcx), span);
808 if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
810 bounds.insert(0, bound);
811 } else {
812 bounds.push(bound);
813 }
814 }
815 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
816 }
817
818 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
819 && !self.tcx().is_const_trait(trait_def_id)
820 {
821 let (def_span, suggestion, suggestion_pre) =
822 match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) {
823 (true, true) => (
824 None,
825 Some(tcx.def_span(trait_def_id).shrink_to_lo()),
826 if self.tcx().features().const_trait_impl() {
827 ""
828 } else {
829 "enable `#![feature(const_trait_impl)]` in your crate and "
830 },
831 ),
832 (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
833 };
834 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
835 span,
836 modifier: constness.as_str(),
837 def_span,
838 trait_name: self.tcx().def_path_str(trait_def_id),
839 suggestion_pre,
840 suggestion,
841 });
842 } else {
843 match predicate_filter {
844 PredicateFilter::SelfTraitThatDefines(..) => {}
846 PredicateFilter::All
847 | PredicateFilter::SelfOnly
848 | PredicateFilter::SelfAndAssociatedTypeBounds => {
849 match constness {
850 hir::BoundConstness::Always(_) => {
851 if polarity == ty::PredicatePolarity::Positive {
852 bounds.push((
853 poly_trait_ref
854 .to_host_effect_clause(tcx, ty::BoundConstness::Const),
855 span,
856 ));
857 }
858 }
859 hir::BoundConstness::Maybe(_) => {
860 }
865 hir::BoundConstness::Never => {}
866 }
867 }
868 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
875 match constness {
876 hir::BoundConstness::Maybe(_) => {
877 if polarity == ty::PredicatePolarity::Positive {
878 bounds.push((
879 poly_trait_ref
880 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
881 span,
882 ));
883 }
884 }
885 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
886 }
887 }
888 }
889 }
890
891 let mut dup_constraints = FxIndexMap::default();
892 for constraint in trait_segment.args().constraints {
893 if polarity != ty::PredicatePolarity::Positive {
897 self.dcx().span_delayed_bug(
898 constraint.span,
899 "negative trait bounds should not have assoc item constraints",
900 );
901 break;
902 }
903
904 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
906 trait_ref.hir_ref_id,
907 poly_trait_ref,
908 constraint,
909 bounds,
910 &mut dup_constraints,
911 constraint.span,
912 predicate_filter,
913 );
914 }
916
917 arg_count
918 }
919
920 fn lower_mono_trait_ref(
924 &self,
925 span: Span,
926 trait_def_id: DefId,
927 self_ty: Ty<'tcx>,
928 trait_segment: &hir::PathSegment<'tcx>,
929 is_impl: bool,
930 ) -> ty::TraitRef<'tcx> {
931 self.report_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
932
933 let (generic_args, _) =
934 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
935 if let Some(c) = trait_segment.args().constraints.first() {
936 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
937 }
938 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
939 }
940
941 fn probe_trait_that_defines_assoc_item(
942 &self,
943 trait_def_id: DefId,
944 assoc_tag: ty::AssocTag,
945 assoc_ident: Ident,
946 ) -> bool {
947 self.tcx()
948 .associated_items(trait_def_id)
949 .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
950 .is_some()
951 }
952
953 fn lower_path_segment(
954 &self,
955 span: Span,
956 did: DefId,
957 item_segment: &hir::PathSegment<'tcx>,
958 ) -> Ty<'tcx> {
959 let tcx = self.tcx();
960 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
961
962 if let DefKind::TyAlias = tcx.def_kind(did)
963 && tcx.type_alias_is_lazy(did)
964 {
965 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
969 Ty::new_alias(tcx, ty::Free, alias_ty)
970 } else {
971 tcx.at(span).type_of(did).instantiate(tcx, args)
972 }
973 }
974
975 #[instrument(level = "debug", skip_all, ret)]
983 fn probe_single_ty_param_bound_for_assoc_item(
984 &self,
985 ty_param_def_id: LocalDefId,
986 ty_param_span: Span,
987 assoc_tag: ty::AssocTag,
988 assoc_ident: Ident,
989 span: Span,
990 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
991 debug!(?ty_param_def_id, ?assoc_ident, ?span);
992 let tcx = self.tcx();
993
994 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
995 debug!("predicates={:#?}", predicates);
996
997 self.probe_single_bound_for_assoc_item(
998 || {
999 let trait_refs = predicates
1000 .iter_identity_copied()
1001 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
1002 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
1003 },
1004 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
1005 assoc_tag,
1006 assoc_ident,
1007 span,
1008 None,
1009 )
1010 }
1011
1012 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1018 fn probe_single_bound_for_assoc_item<I>(
1019 &self,
1020 all_candidates: impl Fn() -> I,
1021 qself: AssocItemQSelf,
1022 assoc_tag: ty::AssocTag,
1023 assoc_ident: Ident,
1024 span: Span,
1025 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1026 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1027 where
1028 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1029 {
1030 let tcx = self.tcx();
1031
1032 let mut matching_candidates = all_candidates().filter(|r| {
1033 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
1034 });
1035
1036 let Some(bound) = matching_candidates.next() else {
1037 return Err(self.report_unresolved_assoc_item(
1038 all_candidates,
1039 qself,
1040 assoc_tag,
1041 assoc_ident,
1042 span,
1043 constraint,
1044 ));
1045 };
1046 debug!(?bound);
1047
1048 if let Some(bound2) = matching_candidates.next() {
1049 debug!(?bound2);
1050
1051 let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
1052 let qself_str = qself.to_string(tcx);
1053 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1054 span,
1055 assoc_kind: assoc_kind_str,
1056 assoc_ident,
1057 qself: &qself_str,
1058 });
1059 err.code(
1061 if let Some(constraint) = constraint
1062 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1063 {
1064 E0222
1065 } else {
1066 E0221
1067 },
1068 );
1069
1070 let mut where_bounds = vec![];
1074 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1075 let bound_id = bound.def_id();
1076 let bound_span = tcx
1077 .associated_items(bound_id)
1078 .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1079 .and_then(|item| tcx.hir_span_if_local(item.def_id));
1080
1081 if let Some(bound_span) = bound_span {
1082 err.span_label(
1083 bound_span,
1084 format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
1085 );
1086 if let Some(constraint) = constraint {
1087 match constraint.kind {
1088 hir::AssocItemConstraintKind::Equality { term } => {
1089 let term: ty::Term<'_> = match term {
1090 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1091 hir::Term::Const(ct) => {
1092 self.lower_const_arg(ct, FeedConstTy::No).into()
1093 }
1094 };
1095 if term.references_error() {
1096 continue;
1097 }
1098 where_bounds.push(format!(
1100 " T: {trait}::{assoc_ident} = {term}",
1101 trait = bound.print_only_trait_path(),
1102 ));
1103 }
1104 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1106 }
1107 } else {
1108 err.span_suggestion_verbose(
1109 span.with_hi(assoc_ident.span.lo()),
1110 "use fully-qualified syntax to disambiguate",
1111 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1112 Applicability::MaybeIncorrect,
1113 );
1114 }
1115 } else {
1116 err.note(format!(
1117 "associated {assoc_kind_str} `{assoc_ident}` could derive from `{}`",
1118 bound.print_only_trait_path(),
1119 ));
1120 }
1121 }
1122 if !where_bounds.is_empty() {
1123 err.help(format!(
1124 "consider introducing a new type parameter `T` and adding `where` constraints:\
1125 \n where\n T: {qself_str},\n{}",
1126 where_bounds.join(",\n"),
1127 ));
1128 let reported = err.emit();
1129 return Err(reported);
1130 }
1131 err.emit();
1132 }
1133
1134 Ok(bound)
1135 }
1136
1137 #[instrument(level = "debug", skip_all, ret)]
1164 pub fn lower_type_relative_ty_path(
1165 &self,
1166 self_ty: Ty<'tcx>,
1167 hir_self_ty: &'tcx hir::Ty<'tcx>,
1168 segment: &'tcx hir::PathSegment<'tcx>,
1169 qpath_hir_id: HirId,
1170 span: Span,
1171 permit_variants: PermitVariants,
1172 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1173 let tcx = self.tcx();
1174 match self.lower_type_relative_path(
1175 self_ty,
1176 hir_self_ty,
1177 segment,
1178 qpath_hir_id,
1179 span,
1180 LowerTypeRelativePathMode::Type(permit_variants),
1181 )? {
1182 TypeRelativePath::AssocItem(def_id, args) => {
1183 let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1184 let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1185 Ok((ty, tcx.def_kind(def_id), def_id))
1186 }
1187 TypeRelativePath::Variant { adt, variant_did } => {
1188 Ok((adt, DefKind::Variant, variant_did))
1189 }
1190 }
1191 }
1192
1193 #[instrument(level = "debug", skip_all, ret)]
1195 fn lower_type_relative_const_path(
1196 &self,
1197 self_ty: Ty<'tcx>,
1198 hir_self_ty: &'tcx hir::Ty<'tcx>,
1199 segment: &'tcx hir::PathSegment<'tcx>,
1200 qpath_hir_id: HirId,
1201 span: Span,
1202 ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1203 let tcx = self.tcx();
1204 let (def_id, args) = match self.lower_type_relative_path(
1205 self_ty,
1206 hir_self_ty,
1207 segment,
1208 qpath_hir_id,
1209 span,
1210 LowerTypeRelativePathMode::Const,
1211 )? {
1212 TypeRelativePath::AssocItem(def_id, args) => {
1213 if !tcx.associated_item(def_id).is_type_const_capable(tcx) {
1214 let mut err = self.dcx().struct_span_err(
1215 span,
1216 "use of trait associated const without `#[type_const]`",
1217 );
1218 err.note("the declaration in the trait must be marked with `#[type_const]`");
1219 return Err(err.emit());
1220 }
1221 (def_id, args)
1222 }
1223 TypeRelativePath::Variant { .. } => {
1226 span_bug!(span, "unexpected variant res for type associated const path")
1227 }
1228 };
1229 Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
1230 }
1231
1232 #[instrument(level = "debug", skip_all, ret)]
1234 fn lower_type_relative_path(
1235 &self,
1236 self_ty: Ty<'tcx>,
1237 hir_self_ty: &'tcx hir::Ty<'tcx>,
1238 segment: &'tcx hir::PathSegment<'tcx>,
1239 qpath_hir_id: HirId,
1240 span: Span,
1241 mode: LowerTypeRelativePathMode,
1242 ) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
1243 debug!(%self_ty, ?segment.ident);
1244 let tcx = self.tcx();
1245
1246 let mut variant_def_id = None;
1248 if let Some(adt_def) = self.probe_adt(span, self_ty) {
1249 if adt_def.is_enum() {
1250 let variant_def = adt_def
1251 .variants()
1252 .iter()
1253 .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
1254 if let Some(variant_def) = variant_def {
1255 if let PermitVariants::Yes = mode.permit_variants() {
1256 tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1257 let _ = self.prohibit_generic_args(
1258 slice::from_ref(segment).iter(),
1259 GenericsArgsErrExtend::EnumVariant {
1260 qself: hir_self_ty,
1261 assoc_segment: segment,
1262 adt_def,
1263 },
1264 );
1265 return Ok(TypeRelativePath::Variant {
1266 adt: self_ty,
1267 variant_did: variant_def.def_id,
1268 });
1269 } else {
1270 variant_def_id = Some(variant_def.def_id);
1271 }
1272 }
1273 }
1274
1275 if let Some((did, args)) = self.probe_inherent_assoc_item(
1277 segment,
1278 adt_def.did(),
1279 self_ty,
1280 qpath_hir_id,
1281 span,
1282 mode.assoc_tag(),
1283 )? {
1284 return Ok(TypeRelativePath::AssocItem(did, args));
1285 }
1286 }
1287
1288 let (item_def_id, bound) = self.resolve_type_relative_path(
1289 self_ty,
1290 hir_self_ty,
1291 mode.assoc_tag(),
1292 segment,
1293 qpath_hir_id,
1294 span,
1295 variant_def_id,
1296 )?;
1297
1298 let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
1299
1300 if let Some(variant_def_id) = variant_def_id {
1301 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
1302 lint.primary_message("ambiguous associated item");
1303 let mut could_refer_to = |kind: DefKind, def_id, also| {
1304 let note_msg = format!(
1305 "`{}` could{} refer to the {} defined here",
1306 segment.ident,
1307 also,
1308 tcx.def_kind_descr(kind, def_id)
1309 );
1310 lint.span_note(tcx.def_span(def_id), note_msg);
1311 };
1312
1313 could_refer_to(DefKind::Variant, variant_def_id, "");
1314 could_refer_to(mode.def_kind(), item_def_id, " also");
1315
1316 lint.span_suggestion(
1317 span,
1318 "use fully-qualified syntax",
1319 format!(
1320 "<{} as {}>::{}",
1321 self_ty,
1322 tcx.item_name(bound.def_id()),
1323 segment.ident
1324 ),
1325 Applicability::MachineApplicable,
1326 );
1327 });
1328 }
1329
1330 Ok(TypeRelativePath::AssocItem(item_def_id, args))
1331 }
1332
1333 fn resolve_type_relative_path(
1335 &self,
1336 self_ty: Ty<'tcx>,
1337 hir_self_ty: &'tcx hir::Ty<'tcx>,
1338 assoc_tag: ty::AssocTag,
1339 segment: &'tcx hir::PathSegment<'tcx>,
1340 qpath_hir_id: HirId,
1341 span: Span,
1342 variant_def_id: Option<DefId>,
1343 ) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
1344 let tcx = self.tcx();
1345
1346 let self_ty_res = match hir_self_ty.kind {
1347 hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
1348 _ => Res::Err,
1349 };
1350
1351 let bound = match (self_ty.kind(), self_ty_res) {
1353 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1354 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1357 self.dcx().span_bug(span, "expected cycle error");
1359 };
1360
1361 self.probe_single_bound_for_assoc_item(
1362 || {
1363 let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
1364 traits::supertraits(tcx, trait_ref)
1365 },
1366 AssocItemQSelf::SelfTyAlias,
1367 assoc_tag,
1368 segment.ident,
1369 span,
1370 None,
1371 )?
1372 }
1373 (
1374 &ty::Param(_),
1375 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1376 ) => self.probe_single_ty_param_bound_for_assoc_item(
1377 param_did.expect_local(),
1378 hir_self_ty.span,
1379 assoc_tag,
1380 segment.ident,
1381 span,
1382 )?,
1383 _ => {
1384 return Err(self.report_unresolved_type_relative_path(
1385 self_ty,
1386 hir_self_ty,
1387 assoc_tag,
1388 segment.ident,
1389 qpath_hir_id,
1390 span,
1391 variant_def_id,
1392 ));
1393 }
1394 };
1395
1396 let assoc_item = self
1397 .probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
1398 .expect("failed to find associated item");
1399
1400 Ok((assoc_item.def_id, bound))
1401 }
1402
1403 fn probe_inherent_assoc_item(
1405 &self,
1406 segment: &hir::PathSegment<'tcx>,
1407 adt_did: DefId,
1408 self_ty: Ty<'tcx>,
1409 block: HirId,
1410 span: Span,
1411 assoc_tag: ty::AssocTag,
1412 ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1413 let tcx = self.tcx();
1414
1415 if !tcx.features().inherent_associated_types() {
1416 match assoc_tag {
1417 ty::AssocTag::Type => return Ok(None),
1425 ty::AssocTag::Const => {
1426 return Err(feature_err(
1430 &tcx.sess,
1431 sym::inherent_associated_types,
1432 span,
1433 "inherent associated types are unstable",
1434 )
1435 .emit());
1436 }
1437 ty::AssocTag::Fn => unreachable!(),
1438 }
1439 }
1440
1441 let name = segment.ident;
1442 let candidates: Vec<_> = tcx
1443 .inherent_impls(adt_did)
1444 .iter()
1445 .filter_map(|&impl_| {
1446 let (item, scope) =
1447 self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1448 Some((impl_, (item.def_id, scope)))
1449 })
1450 .collect();
1451
1452 if candidates.is_empty() {
1453 return Ok(None);
1454 }
1455
1456 let infcx = match self.infcx() {
1463 Some(infcx) => infcx,
1464 None => {
1465 assert!(!self_ty.has_infer());
1466 &tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis())
1467 }
1468 };
1469
1470 let param_env = tcx.param_env(block.owner);
1473
1474 let mut universes = if self_ty.has_escaping_bound_vars() {
1475 vec![None; self_ty.outer_exclusive_binder().as_usize()]
1476 } else {
1477 vec![]
1478 };
1479
1480 let (impl_, (assoc_item, def_scope)) = crate::traits::with_replaced_escaping_bound_vars(
1481 infcx,
1482 &mut universes,
1483 self_ty,
1484 |self_ty| {
1485 self.select_inherent_assoc_candidates(
1486 infcx, name, span, self_ty, param_env, candidates, assoc_tag,
1487 )
1488 },
1489 )?;
1490
1491 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1492
1493 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1497 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1498 let args = tcx.mk_args_from_iter(
1499 std::iter::once(ty::GenericArg::from(self_ty))
1500 .chain(args.into_iter().skip(parent_args.len())),
1501 );
1502
1503 Ok(Some((assoc_item, args)))
1504 }
1505
1506 fn select_inherent_assoc_candidates(
1507 &self,
1508 infcx: &InferCtxt<'tcx>,
1509 name: Ident,
1510 span: Span,
1511 self_ty: Ty<'tcx>,
1512 param_env: ParamEnv<'tcx>,
1513 candidates: Vec<(DefId, (DefId, DefId))>,
1514 assoc_tag: ty::AssocTag,
1515 ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
1516 let tcx = self.tcx();
1517 let mut fulfillment_errors = Vec::new();
1518
1519 let applicable_candidates: Vec<_> = candidates
1520 .iter()
1521 .copied()
1522 .filter(|&(impl_, _)| {
1523 infcx.probe(|_| {
1524 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
1525 let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
1526
1527 let impl_args = infcx.fresh_args_for_item(span, impl_);
1528 let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1529 let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
1530
1531 if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
1533 return false;
1534 }
1535
1536 let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1538 let impl_bounds =
1539 ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
1540 let impl_obligations = traits::predicates_for_generics(
1541 |_, _| ObligationCause::dummy(),
1542 param_env,
1543 impl_bounds,
1544 );
1545 ocx.register_obligations(impl_obligations);
1546
1547 let mut errors = ocx.select_where_possible();
1548 if !errors.is_empty() {
1549 fulfillment_errors.append(&mut errors);
1550 return false;
1551 }
1552
1553 true
1554 })
1555 })
1556 .collect();
1557
1558 match &applicable_candidates[..] {
1559 &[] => Err(self.report_unresolved_inherent_assoc_item(
1560 name,
1561 self_ty,
1562 candidates,
1563 fulfillment_errors,
1564 span,
1565 assoc_tag,
1566 )),
1567
1568 &[applicable_candidate] => Ok(applicable_candidate),
1569
1570 &[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
1571 name,
1572 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1573 span,
1574 )),
1575 }
1576 }
1577
1578 fn probe_assoc_item(
1582 &self,
1583 ident: Ident,
1584 assoc_tag: ty::AssocTag,
1585 block: HirId,
1586 span: Span,
1587 scope: DefId,
1588 ) -> Option<ty::AssocItem> {
1589 let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1590 self.check_assoc_item(item.def_id, ident, scope, block, span);
1591 Some(item)
1592 }
1593
1594 fn probe_assoc_item_unchecked(
1599 &self,
1600 ident: Ident,
1601 assoc_tag: ty::AssocTag,
1602 block: HirId,
1603 scope: DefId,
1604 ) -> Option<(ty::AssocItem, DefId)> {
1605 let tcx = self.tcx();
1606
1607 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1608 let item = tcx
1612 .associated_items(scope)
1613 .filter_by_name_unhygienic(ident.name)
1614 .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1615
1616 Some((*item, def_scope))
1617 }
1618
1619 fn check_assoc_item(
1621 &self,
1622 item_def_id: DefId,
1623 ident: Ident,
1624 scope: DefId,
1625 block: HirId,
1626 span: Span,
1627 ) {
1628 let tcx = self.tcx();
1629
1630 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1631 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1632 span,
1633 kind: tcx.def_descr(item_def_id),
1634 name: ident,
1635 defined_here_label: tcx.def_span(item_def_id),
1636 });
1637 }
1638
1639 tcx.check_stability(item_def_id, Some(block), span, None);
1640 }
1641
1642 fn probe_traits_that_match_assoc_ty(
1643 &self,
1644 qself_ty: Ty<'tcx>,
1645 assoc_ident: Ident,
1646 ) -> Vec<String> {
1647 let tcx = self.tcx();
1648
1649 let infcx_;
1652 let infcx = if let Some(infcx) = self.infcx() {
1653 infcx
1654 } else {
1655 assert!(!qself_ty.has_infer());
1656 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1657 &infcx_
1658 };
1659
1660 tcx.all_traits()
1661 .filter(|trait_def_id| {
1662 tcx.associated_items(*trait_def_id)
1664 .in_definition_order()
1665 .any(|i| {
1666 i.is_type()
1667 && !i.is_impl_trait_in_trait()
1668 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1669 })
1670 && tcx.visibility(*trait_def_id)
1672 .is_accessible_from(self.item_def_id(), tcx)
1673 && tcx.all_impls(*trait_def_id)
1674 .any(|impl_def_id| {
1675 let header = tcx.impl_trait_header(impl_def_id).unwrap();
1676 let trait_ref = header.trait_ref.instantiate(
1677 tcx,
1678 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1679 );
1680
1681 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1682 if value.has_escaping_bound_vars() {
1684 return false;
1685 }
1686 infcx
1687 .can_eq(
1688 ty::ParamEnv::empty(),
1689 trait_ref.self_ty(),
1690 value,
1691 ) && header.polarity != ty::ImplPolarity::Negative
1692 })
1693 })
1694 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1695 .collect()
1696 }
1697
1698 #[instrument(level = "debug", skip_all)]
1700 fn lower_resolved_assoc_ty_path(
1701 &self,
1702 span: Span,
1703 opt_self_ty: Option<Ty<'tcx>>,
1704 item_def_id: DefId,
1705 trait_segment: Option<&hir::PathSegment<'tcx>>,
1706 item_segment: &hir::PathSegment<'tcx>,
1707 ) -> Ty<'tcx> {
1708 match self.lower_resolved_assoc_item_path(
1709 span,
1710 opt_self_ty,
1711 item_def_id,
1712 trait_segment,
1713 item_segment,
1714 ty::AssocTag::Type,
1715 ) {
1716 Ok((item_def_id, item_args)) => {
1717 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1718 }
1719 Err(guar) => Ty::new_error(self.tcx(), guar),
1720 }
1721 }
1722
1723 #[instrument(level = "debug", skip_all)]
1725 fn lower_resolved_assoc_const_path(
1726 &self,
1727 span: Span,
1728 opt_self_ty: Option<Ty<'tcx>>,
1729 item_def_id: DefId,
1730 trait_segment: Option<&hir::PathSegment<'tcx>>,
1731 item_segment: &hir::PathSegment<'tcx>,
1732 ) -> Const<'tcx> {
1733 match self.lower_resolved_assoc_item_path(
1734 span,
1735 opt_self_ty,
1736 item_def_id,
1737 trait_segment,
1738 item_segment,
1739 ty::AssocTag::Const,
1740 ) {
1741 Ok((item_def_id, item_args)) => {
1742 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1743 Const::new_unevaluated(self.tcx(), uv)
1744 }
1745 Err(guar) => Const::new_error(self.tcx(), guar),
1746 }
1747 }
1748
1749 #[instrument(level = "debug", skip_all)]
1751 fn lower_resolved_assoc_item_path(
1752 &self,
1753 span: Span,
1754 opt_self_ty: Option<Ty<'tcx>>,
1755 item_def_id: DefId,
1756 trait_segment: Option<&hir::PathSegment<'tcx>>,
1757 item_segment: &hir::PathSegment<'tcx>,
1758 assoc_tag: ty::AssocTag,
1759 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1760 let tcx = self.tcx();
1761
1762 let trait_def_id = tcx.parent(item_def_id);
1763 debug!(?trait_def_id);
1764
1765 let Some(self_ty) = opt_self_ty else {
1766 return Err(self.report_missing_self_ty_for_resolved_path(
1767 trait_def_id,
1768 span,
1769 item_segment,
1770 assoc_tag,
1771 ));
1772 };
1773 debug!(?self_ty);
1774
1775 let trait_ref =
1776 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
1777 debug!(?trait_ref);
1778
1779 let item_args =
1780 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1781
1782 Ok((item_def_id, item_args))
1783 }
1784
1785 pub fn prohibit_generic_args<'a>(
1786 &self,
1787 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1788 err_extend: GenericsArgsErrExtend<'a>,
1789 ) -> Result<(), ErrorGuaranteed> {
1790 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1791 let mut result = Ok(());
1792 if let Some(_) = args_visitors.clone().next() {
1793 result = Err(self.report_prohibited_generic_args(
1794 segments.clone(),
1795 args_visitors,
1796 err_extend,
1797 ));
1798 }
1799
1800 for segment in segments {
1801 if let Some(c) = segment.args().constraints.first() {
1803 return Err(prohibit_assoc_item_constraint(self, c, None));
1804 }
1805 }
1806
1807 result
1808 }
1809
1810 pub fn probe_generic_path_segments(
1828 &self,
1829 segments: &[hir::PathSegment<'_>],
1830 self_ty: Option<Ty<'tcx>>,
1831 kind: DefKind,
1832 def_id: DefId,
1833 span: Span,
1834 ) -> Vec<GenericPathSegment> {
1835 let tcx = self.tcx();
1881
1882 assert!(!segments.is_empty());
1883 let last = segments.len() - 1;
1884
1885 let mut generic_segments = vec![];
1886
1887 match kind {
1888 DefKind::Ctor(CtorOf::Struct, ..) => {
1890 let generics = tcx.generics_of(def_id);
1893 let generics_def_id = generics.parent.unwrap_or(def_id);
1896 generic_segments.push(GenericPathSegment(generics_def_id, last));
1897 }
1898
1899 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
1901 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
1902 let adt_def = self.probe_adt(span, self_ty).unwrap();
1903 debug_assert!(adt_def.is_enum());
1904 (adt_def.did(), last)
1905 } else if last >= 1 && segments[last - 1].args.is_some() {
1906 let mut def_id = def_id;
1909
1910 if let DefKind::Ctor(..) = kind {
1912 def_id = tcx.parent(def_id);
1913 }
1914
1915 let enum_def_id = tcx.parent(def_id);
1917 (enum_def_id, last - 1)
1918 } else {
1919 let generics = tcx.generics_of(def_id);
1925 (generics.parent.unwrap_or(def_id), last)
1928 };
1929 generic_segments.push(GenericPathSegment(generics_def_id, index));
1930 }
1931
1932 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
1934 generic_segments.push(GenericPathSegment(def_id, last));
1935 }
1936
1937 DefKind::AssocFn | DefKind::AssocConst => {
1939 if segments.len() >= 2 {
1940 let generics = tcx.generics_of(def_id);
1941 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
1942 }
1943 generic_segments.push(GenericPathSegment(def_id, last));
1944 }
1945
1946 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
1947 }
1948
1949 debug!(?generic_segments);
1950
1951 generic_segments
1952 }
1953
1954 #[instrument(level = "debug", skip_all)]
1956 pub fn lower_resolved_ty_path(
1957 &self,
1958 opt_self_ty: Option<Ty<'tcx>>,
1959 path: &hir::Path<'tcx>,
1960 hir_id: HirId,
1961 permit_variants: PermitVariants,
1962 ) -> Ty<'tcx> {
1963 debug!(?path.res, ?opt_self_ty, ?path.segments);
1964 let tcx = self.tcx();
1965
1966 let span = path.span;
1967 match path.res {
1968 Res::Def(DefKind::OpaqueTy, did) => {
1969 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
1971 let item_segment = path.segments.split_last().unwrap();
1972 let _ = self
1973 .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy);
1974 let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0);
1975 Ty::new_opaque(tcx, did, args)
1976 }
1977 Res::Def(
1978 DefKind::Enum
1979 | DefKind::TyAlias
1980 | DefKind::Struct
1981 | DefKind::Union
1982 | DefKind::ForeignTy,
1983 did,
1984 ) => {
1985 assert_eq!(opt_self_ty, None);
1986 let _ = self.prohibit_generic_args(
1987 path.segments.split_last().unwrap().1.iter(),
1988 GenericsArgsErrExtend::None,
1989 );
1990 self.lower_path_segment(span, did, path.segments.last().unwrap())
1991 }
1992 Res::Def(kind @ DefKind::Variant, def_id)
1993 if let PermitVariants::Yes = permit_variants =>
1994 {
1995 assert_eq!(opt_self_ty, None);
1998
1999 let generic_segments =
2000 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
2001 let indices: FxHashSet<_> =
2002 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
2003 let _ = self.prohibit_generic_args(
2004 path.segments.iter().enumerate().filter_map(|(index, seg)| {
2005 if !indices.contains(&index) { Some(seg) } else { None }
2006 }),
2007 GenericsArgsErrExtend::DefVariant(&path.segments),
2008 );
2009
2010 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
2011 self.lower_path_segment(span, *def_id, &path.segments[*index])
2012 }
2013 Res::Def(DefKind::TyParam, def_id) => {
2014 assert_eq!(opt_self_ty, None);
2015 let _ = self.prohibit_generic_args(
2016 path.segments.iter(),
2017 GenericsArgsErrExtend::Param(def_id),
2018 );
2019 self.lower_ty_param(hir_id)
2020 }
2021 Res::SelfTyParam { .. } => {
2022 assert_eq!(opt_self_ty, None);
2024 let _ = self.prohibit_generic_args(
2025 path.segments.iter(),
2026 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2027 GenericsArgsErrExtend::SelfTyParam(
2028 ident.span.shrink_to_hi().to(args.span_ext),
2029 )
2030 } else {
2031 GenericsArgsErrExtend::None
2032 },
2033 );
2034 tcx.types.self_param
2035 }
2036 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
2037 assert_eq!(opt_self_ty, None);
2039 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
2041 let _ = self.prohibit_generic_args(
2042 path.segments.iter(),
2043 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
2044 );
2045 if forbid_generic && ty.has_param() {
2065 let mut err = self.dcx().struct_span_err(
2066 path.span,
2067 "generic `Self` types are currently not permitted in anonymous constants",
2068 );
2069 if let Some(hir::Node::Item(&hir::Item {
2070 kind: hir::ItemKind::Impl(impl_),
2071 ..
2072 })) = tcx.hir_get_if_local(def_id)
2073 {
2074 err.span_note(impl_.self_ty.span, "not a concrete type");
2075 }
2076 let reported = err.emit();
2077 Ty::new_error(tcx, reported)
2078 } else {
2079 ty
2080 }
2081 }
2082 Res::Def(DefKind::AssocTy, def_id) => {
2083 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2084 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2085 Some(trait_)
2086 } else {
2087 None
2088 };
2089 self.lower_resolved_assoc_ty_path(
2090 span,
2091 opt_self_ty,
2092 def_id,
2093 trait_segment,
2094 path.segments.last().unwrap(),
2095 )
2096 }
2097 Res::PrimTy(prim_ty) => {
2098 assert_eq!(opt_self_ty, None);
2099 let _ = self.prohibit_generic_args(
2100 path.segments.iter(),
2101 GenericsArgsErrExtend::PrimTy(prim_ty),
2102 );
2103 match prim_ty {
2104 hir::PrimTy::Bool => tcx.types.bool,
2105 hir::PrimTy::Char => tcx.types.char,
2106 hir::PrimTy::Int(it) => Ty::new_int(tcx, ty::int_ty(it)),
2107 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, ty::uint_ty(uit)),
2108 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ty::float_ty(ft)),
2109 hir::PrimTy::Str => tcx.types.str_,
2110 }
2111 }
2112 Res::Err => {
2113 let e = self
2114 .tcx()
2115 .dcx()
2116 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2117 Ty::new_error(tcx, e)
2118 }
2119 Res::Def(..) => {
2120 assert_eq!(
2121 path.segments.get(0).map(|seg| seg.ident.name),
2122 Some(kw::SelfUpper),
2123 "only expected incorrect resolution for `Self`"
2124 );
2125 Ty::new_error(
2126 self.tcx(),
2127 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2128 )
2129 }
2130 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2131 }
2132 }
2133
2134 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2139 let tcx = self.tcx();
2140 match tcx.named_bound_var(hir_id) {
2141 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2142 let name = tcx.item_name(def_id.to_def_id());
2143 let br = ty::BoundTy {
2144 var: ty::BoundVar::from_u32(index),
2145 kind: ty::BoundTyKind::Param(def_id.to_def_id(), name),
2146 };
2147 Ty::new_bound(tcx, debruijn, br)
2148 }
2149 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2150 let item_def_id = tcx.hir_ty_param_owner(def_id);
2151 let generics = tcx.generics_of(item_def_id);
2152 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2153 Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2154 }
2155 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2156 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2157 }
2158 }
2159
2160 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2165 let tcx = self.tcx();
2166
2167 match tcx.named_bound_var(path_hir_id) {
2168 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2169 let item_def_id = tcx.parent(param_def_id);
2172 let generics = tcx.generics_of(item_def_id);
2173 let index = generics.param_def_id_to_index[¶m_def_id];
2174 let name = tcx.item_name(param_def_id);
2175 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2176 }
2177 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2178 ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
2179 }
2180 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2181 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2182 }
2183 }
2184
2185 #[instrument(skip(self), level = "debug")]
2187 pub fn lower_const_arg(
2188 &self,
2189 const_arg: &hir::ConstArg<'tcx>,
2190 feed: FeedConstTy<'_, 'tcx>,
2191 ) -> Const<'tcx> {
2192 let tcx = self.tcx();
2193
2194 if let FeedConstTy::Param(param_def_id, args) = feed
2195 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2196 {
2197 let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2198
2199 if tcx.features().generic_const_parameter_types()
2208 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2209 {
2210 let e = self.dcx().span_err(
2211 const_arg.span(),
2212 "anonymous constants with lifetimes in their type are not yet supported",
2213 );
2214 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2215 return ty::Const::new_error(tcx, e);
2216 }
2217 if anon_const_type.has_non_region_infer() {
2221 let e = self.dcx().span_err(
2222 const_arg.span(),
2223 "anonymous constants with inferred types are not yet supported",
2224 );
2225 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2226 return ty::Const::new_error(tcx, e);
2227 }
2228 if anon_const_type.has_non_region_param() {
2231 let e = self.dcx().span_err(
2232 const_arg.span(),
2233 "anonymous constants referencing generics are not yet supported",
2234 );
2235 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2236 return ty::Const::new_error(tcx, e);
2237 }
2238
2239 tcx.feed_anon_const_type(
2240 anon.def_id,
2241 ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2242 );
2243 }
2244
2245 let hir_id = const_arg.hir_id;
2246 match const_arg.kind {
2247 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2248 debug!(?maybe_qself, ?path);
2249 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2250 self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2251 }
2252 hir::ConstArgKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2253 debug!(?hir_self_ty, ?segment);
2254 let self_ty = self.lower_ty(hir_self_ty);
2255 self.lower_type_relative_const_path(
2256 self_ty,
2257 hir_self_ty,
2258 segment,
2259 hir_id,
2260 const_arg.span(),
2261 )
2262 .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2263 }
2264 hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
2265 ty::Const::new_error_with_message(
2266 tcx,
2267 qpath.span(),
2268 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
2269 )
2270 }
2271 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2272 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2273 }
2274 }
2275
2276 fn lower_resolved_const_path(
2278 &self,
2279 opt_self_ty: Option<Ty<'tcx>>,
2280 path: &hir::Path<'tcx>,
2281 hir_id: HirId,
2282 ) -> Const<'tcx> {
2283 let tcx = self.tcx();
2284 let span = path.span;
2285 match path.res {
2286 Res::Def(DefKind::ConstParam, def_id) => {
2287 assert_eq!(opt_self_ty, None);
2288 let _ = self.prohibit_generic_args(
2289 path.segments.iter(),
2290 GenericsArgsErrExtend::Param(def_id),
2291 );
2292 self.lower_const_param(def_id, hir_id)
2293 }
2294 Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2295 assert_eq!(opt_self_ty, None);
2296 let _ = self.prohibit_generic_args(
2297 path.segments.split_last().unwrap().1.iter(),
2298 GenericsArgsErrExtend::None,
2299 );
2300 let args = self.lower_generic_args_of_path_segment(
2301 span,
2302 did,
2303 path.segments.last().unwrap(),
2304 );
2305 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2306 }
2307 Res::Def(DefKind::AssocConst, did) => {
2308 let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2309 let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2310 Some(trait_)
2311 } else {
2312 None
2313 };
2314 self.lower_resolved_assoc_const_path(
2315 span,
2316 opt_self_ty,
2317 did,
2318 trait_segment,
2319 path.segments.last().unwrap(),
2320 )
2321 }
2322 Res::Def(DefKind::Static { .. }, _) => {
2323 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2324 }
2325 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2327 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2328 let args = self.lower_generic_args_of_path_segment(
2329 span,
2330 did,
2331 path.segments.last().unwrap(),
2332 );
2333 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2334 }
2335
2336 res @ (Res::Def(
2339 DefKind::Mod
2340 | DefKind::Enum
2341 | DefKind::Variant
2342 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2343 | DefKind::Struct
2344 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2345 | DefKind::OpaqueTy
2346 | DefKind::TyAlias
2347 | DefKind::TraitAlias
2348 | DefKind::AssocTy
2349 | DefKind::Union
2350 | DefKind::Trait
2351 | DefKind::ForeignTy
2352 | DefKind::TyParam
2353 | DefKind::Macro(_)
2354 | DefKind::LifetimeParam
2355 | DefKind::Use
2356 | DefKind::ForeignMod
2357 | DefKind::AnonConst
2358 | DefKind::InlineConst
2359 | DefKind::Field
2360 | DefKind::Impl { .. }
2361 | DefKind::Closure
2362 | DefKind::ExternCrate
2363 | DefKind::GlobalAsm
2364 | DefKind::SyntheticCoroutineBody,
2365 _,
2366 )
2367 | Res::PrimTy(_)
2368 | Res::SelfTyParam { .. }
2369 | Res::SelfTyAlias { .. }
2370 | Res::SelfCtor(_)
2371 | Res::Local(_)
2372 | Res::ToolMod
2373 | Res::NonMacroAttr(_)
2374 | Res::Err) => Const::new_error_with_message(
2375 tcx,
2376 span,
2377 format!("invalid Res {res:?} for const path"),
2378 ),
2379 }
2380 }
2381
2382 #[instrument(skip(self), level = "debug")]
2384 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2385 let tcx = self.tcx();
2386
2387 let expr = &tcx.hir_body(anon.body).value;
2388 debug!(?expr);
2389
2390 let ty = tcx.type_of(anon.def_id).instantiate_identity();
2394
2395 match self.try_lower_anon_const_lit(ty, expr) {
2396 Some(v) => v,
2397 None => ty::Const::new_unevaluated(
2398 tcx,
2399 ty::UnevaluatedConst {
2400 def: anon.def_id.to_def_id(),
2401 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2402 },
2403 ),
2404 }
2405 }
2406
2407 #[instrument(skip(self), level = "debug")]
2408 fn try_lower_anon_const_lit(
2409 &self,
2410 ty: Ty<'tcx>,
2411 expr: &'tcx hir::Expr<'tcx>,
2412 ) -> Option<Const<'tcx>> {
2413 let tcx = self.tcx();
2414
2415 let expr = match &expr.kind {
2418 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2419 block.expr.as_ref().unwrap()
2420 }
2421 _ => expr,
2422 };
2423
2424 if let hir::ExprKind::Path(hir::QPath::Resolved(
2425 _,
2426 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2427 )) = expr.kind
2428 {
2429 span_bug!(
2430 expr.span,
2431 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2432 );
2433 };
2434
2435 let lit_input = match expr.kind {
2436 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
2437 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2438 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
2439 _ => None,
2440 },
2441 _ => None,
2442 };
2443
2444 lit_input
2445 .filter(|l| !l.ty.has_aliases())
2448 .map(|l| tcx.at(expr.span).lit_to_const(l))
2449 }
2450
2451 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2452 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2453 match idx {
2454 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2455 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2456 }
2457 }
2458
2459 #[instrument(level = "debug", skip(self), ret)]
2461 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2462 let tcx = self.tcx();
2463
2464 let result_ty = match &hir_ty.kind {
2465 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2466 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2467 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2468 hir::TyKind::Ref(region, mt) => {
2469 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2470 debug!(?r);
2471 let t = self.lower_ty(mt.ty);
2472 Ty::new_ref(tcx, r, t, mt.mutbl)
2473 }
2474 hir::TyKind::Never => tcx.types.never,
2475 hir::TyKind::Tup(fields) => {
2476 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2477 }
2478 hir::TyKind::BareFn(bf) => {
2479 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span);
2480
2481 Ty::new_fn_ptr(
2482 tcx,
2483 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2484 )
2485 }
2486 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2487 tcx,
2488 ty::Binder::bind_with_vars(
2489 self.lower_ty(binder.inner_ty),
2490 tcx.late_bound_vars(hir_ty.hir_id),
2491 ),
2492 ),
2493 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2494 let lifetime = tagged_ptr.pointer();
2495 let repr = tagged_ptr.tag();
2496
2497 if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2498 Ty::new_error(tcx, guar)
2502 } else {
2503 let repr = match repr {
2504 TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2505 TraitObjectSyntax::DynStar => ty::DynStar,
2506 };
2507 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2508 }
2509 }
2510 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2514 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2515 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2516 }) =>
2517 {
2518 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2519 Ty::new_error(tcx, guar)
2520 }
2521 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2522 debug!(?maybe_qself, ?path);
2523 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2524 self.lower_resolved_ty_path(opt_self_ty, path, hir_ty.hir_id, PermitVariants::No)
2525 }
2526 &hir::TyKind::OpaqueDef(opaque_ty) => {
2527 let in_trait = match opaque_ty.origin {
2531 hir::OpaqueTyOrigin::FnReturn {
2532 in_trait_or_impl: Some(hir::RpitContext::Trait),
2533 ..
2534 }
2535 | hir::OpaqueTyOrigin::AsyncFn {
2536 in_trait_or_impl: Some(hir::RpitContext::Trait),
2537 ..
2538 } => true,
2539 hir::OpaqueTyOrigin::FnReturn {
2540 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2541 ..
2542 }
2543 | hir::OpaqueTyOrigin::AsyncFn {
2544 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2545 ..
2546 }
2547 | hir::OpaqueTyOrigin::TyAlias { .. } => false,
2548 };
2549
2550 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2551 }
2552 hir::TyKind::TraitAscription(hir_bounds) => {
2553 let self_ty = self.ty_infer(None, hir_ty.span);
2556 let mut bounds = Vec::new();
2557 self.lower_bounds(
2558 self_ty,
2559 hir_bounds.iter(),
2560 &mut bounds,
2561 ty::List::empty(),
2562 PredicateFilter::All,
2563 );
2564 self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2565 self_ty
2566 }
2567 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2571 if segment.args.is_some_and(|args| {
2572 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2573 }) =>
2574 {
2575 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2576 Ty::new_error(tcx, guar)
2577 }
2578 hir::TyKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2579 debug!(?hir_self_ty, ?segment);
2580 let self_ty = self.lower_ty(hir_self_ty);
2581 self.lower_type_relative_ty_path(
2582 self_ty,
2583 hir_self_ty,
2584 segment,
2585 hir_ty.hir_id,
2586 hir_ty.span,
2587 PermitVariants::No,
2588 )
2589 .map(|(ty, _, _)| ty)
2590 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2591 }
2592 &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
2593 let def_id = tcx.require_lang_item(lang_item, Some(span));
2594 let (args, _) = self.lower_generic_args_of_path(
2595 span,
2596 def_id,
2597 &[],
2598 &hir::PathSegment::invalid(),
2599 None,
2600 );
2601 tcx.at(span).type_of(def_id).instantiate(tcx, args)
2602 }
2603 hir::TyKind::Array(ty, length) => {
2604 let length = self.lower_const_arg(length, FeedConstTy::No);
2605 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2606 }
2607 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2608 hir::TyKind::Infer(()) => {
2609 self.ty_infer(None, hir_ty.span)
2614 }
2615 hir::TyKind::Pat(ty, pat) => {
2616 let ty_span = ty.span;
2617 let ty = self.lower_ty(ty);
2618 let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
2619 Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
2620 Err(guar) => Ty::new_error(tcx, guar),
2621 };
2622 self.record_ty(pat.hir_id, ty, pat.span);
2623 pat_ty
2624 }
2625 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2626 };
2627
2628 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2629 result_ty
2630 }
2631
2632 fn lower_pat_ty_pat(
2633 &self,
2634 ty: Ty<'tcx>,
2635 ty_span: Span,
2636 pat: &hir::TyPat<'tcx>,
2637 ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
2638 let tcx = self.tcx();
2639 match pat.kind {
2640 hir::TyPatKind::Range(start, end) => {
2641 match ty.kind() {
2642 ty::Int(_) | ty::Uint(_) | ty::Char => {
2645 let start = self.lower_const_arg(start, FeedConstTy::No);
2646 let end = self.lower_const_arg(end, FeedConstTy::No);
2647 Ok(ty::PatternKind::Range { start, end })
2648 }
2649 _ => Err(self
2650 .dcx()
2651 .span_delayed_bug(ty_span, "invalid base type for range pattern")),
2652 }
2653 }
2654 hir::TyPatKind::Or(patterns) => {
2655 self.tcx()
2656 .mk_patterns_from_iter(patterns.iter().map(|pat| {
2657 self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
2658 }))
2659 .map(ty::PatternKind::Or)
2660 }
2661 hir::TyPatKind::Err(e) => Err(e),
2662 }
2663 }
2664
2665 #[instrument(level = "debug", skip(self), ret)]
2667 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
2668 let tcx = self.tcx();
2669
2670 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2671 debug!(?lifetimes);
2672
2673 let def_id = if in_trait {
2677 tcx.associated_type_for_impl_trait_in_trait(def_id).to_def_id()
2678 } else {
2679 def_id.to_def_id()
2680 };
2681
2682 let generics = tcx.generics_of(def_id);
2683 debug!(?generics);
2684
2685 let offset = generics.count() - lifetimes.len();
2689
2690 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2691 if let Some(i) = (param.index as usize).checked_sub(offset) {
2692 let (lifetime, _) = lifetimes[i];
2693 self.lower_resolved_lifetime(lifetime).into()
2694 } else {
2695 tcx.mk_param_from_def(param)
2696 }
2697 });
2698 debug!(?args);
2699
2700 if in_trait {
2701 Ty::new_projection_from_args(tcx, def_id, args)
2702 } else {
2703 Ty::new_opaque(tcx, def_id, args)
2704 }
2705 }
2706
2707 pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
2708 match ty.kind {
2709 hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => {
2710 self.record_ty(ty.hir_id, expected_ty, ty.span);
2711 expected_ty
2712 }
2713 _ => self.lower_ty(ty),
2714 }
2715 }
2716
2717 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2719 pub fn lower_fn_ty(
2720 &self,
2721 hir_id: HirId,
2722 safety: hir::Safety,
2723 abi: rustc_abi::ExternAbi,
2724 decl: &hir::FnDecl<'tcx>,
2725 generics: Option<&hir::Generics<'_>>,
2726 hir_ty: Option<&hir::Ty<'_>>,
2727 ) -> ty::PolyFnSig<'tcx> {
2728 let tcx = self.tcx();
2729 let bound_vars = tcx.late_bound_vars(hir_id);
2730 debug!(?bound_vars);
2731
2732 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2733
2734 debug!(?output_ty);
2735
2736 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2737 let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2738
2739 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2740 tcx.hir_node(hir_id)
2741 {
2742 check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2743 }
2744
2745 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
2747
2748 if !bare_fn_ty.references_error() {
2749 let inputs = bare_fn_ty.inputs();
2756 let late_bound_in_args =
2757 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2758 let output = bare_fn_ty.output();
2759 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2760
2761 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2762 struct_span_code_err!(
2763 self.dcx(),
2764 decl.output.span(),
2765 E0581,
2766 "return type references {}, which is not constrained by the fn input types",
2767 br_name
2768 )
2769 });
2770 }
2771
2772 bare_fn_ty
2773 }
2774
2775 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2780 &self,
2781 fn_hir_id: HirId,
2782 arg_idx: Option<usize>,
2783 ) -> Option<Ty<'tcx>> {
2784 let tcx = self.tcx();
2785 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2786 tcx.hir_node(fn_hir_id)
2787 else {
2788 return None;
2789 };
2790 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2791
2792 let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
2793
2794 let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
2795 tcx,
2796 *ident,
2797 ty::AssocTag::Fn,
2798 trait_ref.def_id,
2799 )?;
2800
2801 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2802 tcx,
2803 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2804 );
2805 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2806
2807 Some(if let Some(arg_idx) = arg_idx {
2808 *fn_sig.inputs().get(arg_idx)?
2809 } else {
2810 fn_sig.output()
2811 })
2812 }
2813
2814 #[instrument(level = "trace", skip(self, generate_err))]
2815 fn validate_late_bound_regions<'cx>(
2816 &'cx self,
2817 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2818 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2819 generate_err: impl Fn(&str) -> Diag<'cx>,
2820 ) {
2821 for br in referenced_regions.difference(&constrained_regions) {
2822 let br_name = match *br {
2823 ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2824 | ty::BoundRegionKind::Anon
2825 | ty::BoundRegionKind::ClosureEnv => "an anonymous lifetime".to_string(),
2826 ty::BoundRegionKind::Named(_, name) => format!("lifetime `{name}`"),
2827 };
2828
2829 let mut err = generate_err(&br_name);
2830
2831 if let ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2832 | ty::BoundRegionKind::Anon = *br
2833 {
2834 err.note(
2841 "lifetimes appearing in an associated or opaque type are not considered constrained",
2842 );
2843 err.note("consider introducing a named lifetime parameter");
2844 }
2845
2846 err.emit();
2847 }
2848 }
2849
2850 #[instrument(level = "debug", skip(self, span), ret)]
2858 fn compute_object_lifetime_bound(
2859 &self,
2860 span: Span,
2861 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2862 ) -> Option<ty::Region<'tcx>> {
2864 let tcx = self.tcx();
2865
2866 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2869
2870 if derived_region_bounds.is_empty() {
2873 return None;
2874 }
2875
2876 if derived_region_bounds.iter().any(|r| r.is_static()) {
2879 return Some(tcx.lifetimes.re_static);
2880 }
2881
2882 let r = derived_region_bounds[0];
2886 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2887 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2888 }
2889 Some(r)
2890 }
2891}