1mod bounds;
17mod cmse;
18mod dyn_compatibility;
19pub mod errors;
20pub mod generics;
21mod lint;
22
23use std::assert_matches::assert_matches;
24use std::slice;
25
26use rustc_ast::TraitObjectSyntax;
27use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
28use rustc_errors::codes::*;
29use rustc_errors::{
30 Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
31};
32use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
33use rustc_hir::def_id::{DefId, LocalDefId};
34use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
35use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
36use rustc_infer::traits::ObligationCause;
37use rustc_middle::middle::stability::AllowUnstable;
38use rustc_middle::mir::interpret::LitToConstInput;
39use rustc_middle::ty::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::edit_distance::find_best_match_for_name;
48use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
49use rustc_trait_selection::infer::InferCtxtExt;
50use rustc_trait_selection::traits::wf::object_region_bounds;
51use rustc_trait_selection::traits::{self, ObligationCtxt};
52use tracing::{debug, instrument};
53
54use self::errors::assoc_kind_str;
55use crate::check::check_abi_fn_ptr;
56use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
57use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
58use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
59use crate::middle::resolve_bound_vars as rbv;
60use crate::require_c_abi_if_c_variadic;
61
62#[derive(Debug)]
64pub struct GenericPathSegment(pub DefId, pub usize);
65
66#[derive(Copy, Clone, Debug)]
67pub enum PredicateFilter {
68 All,
70
71 SelfOnly,
73
74 SelfTraitThatDefines(Ident),
78
79 SelfAndAssociatedTypeBounds,
83
84 ConstIfConst,
86
87 SelfConstIfConst,
89}
90
91#[derive(Debug)]
92pub enum RegionInferReason<'a> {
93 ExplicitObjectLifetime,
95 ObjectLifetimeDefault,
97 Param(&'a ty::GenericParamDef),
99 RegionPredicate,
100 Reference,
101 OutlivesBound,
102}
103
104pub trait HirTyLowerer<'tcx> {
109 fn tcx(&self) -> TyCtxt<'tcx>;
110
111 fn dcx(&self) -> DiagCtxtHandle<'_>;
112
113 fn item_def_id(&self) -> LocalDefId;
115
116 fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
118
119 fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
121
122 fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
124
125 fn register_trait_ascription_bounds(
126 &self,
127 bounds: Vec<(ty::Clause<'tcx>, Span)>,
128 hir_id: HirId,
129 span: Span,
130 );
131
132 fn probe_ty_param_bounds(
147 &self,
148 span: Span,
149 def_id: LocalDefId,
150 assoc_name: Ident,
151 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
152
153 fn lower_assoc_shared(
166 &self,
167 span: Span,
168 item_def_id: DefId,
169 item_segment: &hir::PathSegment<'tcx>,
170 poly_trait_ref: ty::PolyTraitRef<'tcx>,
171 kind: ty::AssocKind,
172 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
173
174 fn lower_fn_sig(
175 &self,
176 decl: &hir::FnDecl<'tcx>,
177 generics: Option<&hir::Generics<'_>>,
178 hir_id: HirId,
179 hir_ty: Option<&hir::Ty<'_>>,
180 ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
181
182 fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
189
190 fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
192
193 fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
195
196 fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
201 where
202 Self: Sized,
203 {
204 self
205 }
206}
207
208enum AssocItemQSelf {
212 Trait(DefId),
213 TyParam(LocalDefId, Span),
214 SelfTyAlias,
215}
216
217impl AssocItemQSelf {
218 fn to_string(&self, tcx: TyCtxt<'_>) -> String {
219 match *self {
220 Self::Trait(def_id) => tcx.def_path_str(def_id),
221 Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
222 Self::SelfTyAlias => kw::SelfUpper.to_string(),
223 }
224 }
225}
226
227#[derive(Debug, Clone, Copy)]
234pub enum FeedConstTy<'a, 'tcx> {
235 Param(DefId, &'a [ty::GenericArg<'tcx>]),
243 No,
245}
246
247#[derive(Debug, Clone, Copy)]
248enum LowerAssocMode {
249 Type { permit_variants: bool },
250 Const,
251}
252
253impl LowerAssocMode {
254 fn kind(self) -> ty::AssocKind {
255 match self {
256 LowerAssocMode::Type { .. } => ty::AssocKind::Type,
257 LowerAssocMode::Const => ty::AssocKind::Const,
258 }
259 }
260
261 fn def_kind(self) -> DefKind {
262 match self {
263 LowerAssocMode::Type { .. } => DefKind::AssocTy,
264 LowerAssocMode::Const => DefKind::AssocConst,
265 }
266 }
267
268 fn permit_variants(self) -> bool {
269 match self {
270 LowerAssocMode::Type { permit_variants } => permit_variants,
271 LowerAssocMode::Const => false,
273 }
274 }
275}
276
277#[derive(Debug, Clone, Copy)]
278enum LoweredAssoc<'tcx> {
279 Term(DefId, GenericArgsRef<'tcx>),
280 Variant { adt: Ty<'tcx>, variant_did: DefId },
281}
282
283#[derive(Copy, Clone, PartialEq, Debug)]
293pub enum ExplicitLateBound {
294 Yes,
295 No,
296}
297
298#[derive(Copy, Clone, PartialEq)]
299pub enum IsMethodCall {
300 Yes,
301 No,
302}
303
304#[derive(Copy, Clone, PartialEq)]
307pub(crate) enum GenericArgPosition {
308 Type,
309 Value, MethodCall,
311}
312
313#[derive(Clone, Debug)]
316pub struct GenericArgCountMismatch {
317 pub reported: ErrorGuaranteed,
318 pub invalid_args: Vec<usize>,
320}
321
322#[derive(Clone, Debug)]
325pub struct GenericArgCountResult {
326 pub explicit_late_bound: ExplicitLateBound,
327 pub correct: Result<(), GenericArgCountMismatch>,
328}
329
330pub trait GenericArgsLowerer<'a, 'tcx> {
335 fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
336
337 fn provided_kind(
338 &mut self,
339 preceding_args: &[ty::GenericArg<'tcx>],
340 param: &ty::GenericParamDef,
341 arg: &GenericArg<'tcx>,
342 ) -> ty::GenericArg<'tcx>;
343
344 fn inferred_kind(
345 &mut self,
346 preceding_args: &[ty::GenericArg<'tcx>],
347 param: &ty::GenericParamDef,
348 infer_args: bool,
349 ) -> ty::GenericArg<'tcx>;
350}
351
352impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
353 #[instrument(level = "debug", skip(self), ret)]
355 pub fn lower_lifetime(
356 &self,
357 lifetime: &hir::Lifetime,
358 reason: RegionInferReason<'_>,
359 ) -> ty::Region<'tcx> {
360 if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
361 self.lower_resolved_lifetime(resolved)
362 } else {
363 self.re_infer(lifetime.ident.span, reason)
364 }
365 }
366
367 #[instrument(level = "debug", skip(self), ret)]
369 pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
370 let tcx = self.tcx();
371 let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id));
372
373 match resolved {
374 rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
375
376 rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
377 let name = lifetime_name(def_id);
378 let br = ty::BoundRegion {
379 var: ty::BoundVar::from_u32(index),
380 kind: ty::BoundRegionKind::Named(def_id.to_def_id(), name),
381 };
382 ty::Region::new_bound(tcx, debruijn, br)
383 }
384
385 rbv::ResolvedArg::EarlyBound(def_id) => {
386 let name = tcx.hir_ty_param_name(def_id);
387 let item_def_id = tcx.hir_ty_param_owner(def_id);
388 let generics = tcx.generics_of(item_def_id);
389 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
390 ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
391 }
392
393 rbv::ResolvedArg::Free(scope, id) => {
394 let name = lifetime_name(id);
395 ty::Region::new_late_param(
396 tcx,
397 scope.to_def_id(),
398 ty::LateParamRegionKind::Named(id.to_def_id(), name),
399 )
400
401 }
403
404 rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
405 }
406 }
407
408 pub fn lower_generic_args_of_path_segment(
409 &self,
410 span: Span,
411 def_id: DefId,
412 item_segment: &hir::PathSegment<'tcx>,
413 ) -> GenericArgsRef<'tcx> {
414 let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
415 if let Some(c) = item_segment.args().constraints.first() {
416 prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
417 }
418 args
419 }
420
421 #[instrument(level = "debug", skip(self, span), ret)]
456 fn lower_generic_args_of_path(
457 &self,
458 span: Span,
459 def_id: DefId,
460 parent_args: &[ty::GenericArg<'tcx>],
461 segment: &hir::PathSegment<'tcx>,
462 self_ty: Option<Ty<'tcx>>,
463 ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
464 let tcx = self.tcx();
469 let generics = tcx.generics_of(def_id);
470 debug!(?generics);
471
472 if generics.has_self {
473 if generics.parent.is_some() {
474 assert!(!parent_args.is_empty())
477 } else {
478 assert!(self_ty.is_some());
480 }
481 } else {
482 assert!(self_ty.is_none());
483 }
484
485 let arg_count = check_generic_arg_count(
486 self,
487 def_id,
488 segment,
489 generics,
490 GenericArgPosition::Type,
491 self_ty.is_some(),
492 );
493
494 if generics.is_own_empty() {
499 return (tcx.mk_args(parent_args), arg_count);
500 }
501
502 struct GenericArgsCtxt<'a, 'tcx> {
503 lowerer: &'a dyn HirTyLowerer<'tcx>,
504 def_id: DefId,
505 generic_args: &'a GenericArgs<'tcx>,
506 span: Span,
507 infer_args: bool,
508 incorrect_args: &'a Result<(), GenericArgCountMismatch>,
509 }
510
511 impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
512 fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
513 if did == self.def_id {
514 (Some(self.generic_args), self.infer_args)
515 } else {
516 (None, false)
518 }
519 }
520
521 fn provided_kind(
522 &mut self,
523 preceding_args: &[ty::GenericArg<'tcx>],
524 param: &ty::GenericParamDef,
525 arg: &GenericArg<'tcx>,
526 ) -> ty::GenericArg<'tcx> {
527 let tcx = self.lowerer.tcx();
528
529 if let Err(incorrect) = self.incorrect_args {
530 if incorrect.invalid_args.contains(&(param.index as usize)) {
531 return param.to_error(tcx);
532 }
533 }
534
535 let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
536 if has_default {
537 tcx.check_optional_stability(
538 param.def_id,
539 Some(arg.hir_id()),
540 arg.span(),
541 None,
542 AllowUnstable::No,
543 |_, _| {
544 },
550 );
551 }
552 self.lowerer.lower_ty(ty).into()
553 };
554
555 match (¶m.kind, arg) {
556 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
557 self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
558 }
559 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
560 handle_ty_args(has_default, ty.as_unambig_ty())
562 }
563 (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
564 handle_ty_args(has_default, &inf.to_ty())
565 }
566 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
567 .lowerer
568 .lower_const_arg(
570 ct.as_unambig_ct(),
571 FeedConstTy::Param(param.def_id, preceding_args),
572 )
573 .into(),
574 (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
575 self.lowerer.ct_infer(Some(param), inf.span).into()
576 }
577 (kind, arg) => span_bug!(
578 self.span,
579 "mismatched path argument for kind {kind:?}: found arg {arg:?}"
580 ),
581 }
582 }
583
584 fn inferred_kind(
585 &mut self,
586 preceding_args: &[ty::GenericArg<'tcx>],
587 param: &ty::GenericParamDef,
588 infer_args: bool,
589 ) -> ty::GenericArg<'tcx> {
590 let tcx = self.lowerer.tcx();
591
592 if let Err(incorrect) = self.incorrect_args {
593 if incorrect.invalid_args.contains(&(param.index as usize)) {
594 return param.to_error(tcx);
595 }
596 }
597 match param.kind {
598 GenericParamDefKind::Lifetime => {
599 self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
600 }
601 GenericParamDefKind::Type { has_default, .. } => {
602 if !infer_args && has_default {
603 if let Some(prev) =
605 preceding_args.iter().find_map(|arg| match arg.unpack() {
606 GenericArgKind::Type(ty) => ty.error_reported().err(),
607 _ => None,
608 })
609 {
610 return Ty::new_error(tcx, prev).into();
612 }
613 tcx.at(self.span)
614 .type_of(param.def_id)
615 .instantiate(tcx, preceding_args)
616 .into()
617 } else if infer_args {
618 self.lowerer.ty_infer(Some(param), self.span).into()
619 } else {
620 Ty::new_misc_error(tcx).into()
622 }
623 }
624 GenericParamDefKind::Const { has_default, .. } => {
625 let ty = tcx
626 .at(self.span)
627 .type_of(param.def_id)
628 .instantiate(tcx, preceding_args);
629 if let Err(guar) = ty.error_reported() {
630 return ty::Const::new_error(tcx, guar).into();
631 }
632 if !infer_args && has_default {
633 tcx.const_param_default(param.def_id)
634 .instantiate(tcx, preceding_args)
635 .into()
636 } else if infer_args {
637 self.lowerer.ct_infer(Some(param), self.span).into()
638 } else {
639 ty::Const::new_misc_error(tcx).into()
641 }
642 }
643 }
644 }
645 }
646
647 let mut args_ctx = GenericArgsCtxt {
648 lowerer: self,
649 def_id,
650 span,
651 generic_args: segment.args(),
652 infer_args: segment.infer_args,
653 incorrect_args: &arg_count.correct,
654 };
655 let args = lower_generic_args(
656 self,
657 def_id,
658 parent_args,
659 self_ty.is_some(),
660 self_ty,
661 &arg_count,
662 &mut args_ctx,
663 );
664
665 (args, arg_count)
666 }
667
668 #[instrument(level = "debug", skip(self))]
669 pub fn lower_generic_args_of_assoc_item(
670 &self,
671 span: Span,
672 item_def_id: DefId,
673 item_segment: &hir::PathSegment<'tcx>,
674 parent_args: GenericArgsRef<'tcx>,
675 ) -> GenericArgsRef<'tcx> {
676 let (args, _) =
677 self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
678 if let Some(c) = item_segment.args().constraints.first() {
679 prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
680 }
681 args
682 }
683
684 pub fn lower_impl_trait_ref(
688 &self,
689 trait_ref: &hir::TraitRef<'tcx>,
690 self_ty: Ty<'tcx>,
691 ) -> ty::TraitRef<'tcx> {
692 let _ = self.prohibit_generic_args(
693 trait_ref.path.segments.split_last().unwrap().1.iter(),
694 GenericsArgsErrExtend::None,
695 );
696
697 self.lower_mono_trait_ref(
698 trait_ref.path.span,
699 trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
700 self_ty,
701 trait_ref.path.segments.last().unwrap(),
702 true,
703 )
704 }
705
706 #[instrument(level = "debug", skip(self, span, constness, bounds))]
730 pub(crate) fn lower_poly_trait_ref(
731 &self,
732 trait_ref: &hir::TraitRef<'tcx>,
733 span: Span,
734 constness: hir::BoundConstness,
735 polarity: hir::BoundPolarity,
736 self_ty: Ty<'tcx>,
737 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
738 predicate_filter: PredicateFilter,
739 ) -> GenericArgCountResult {
740 let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
741 let trait_segment = trait_ref.path.segments.last().unwrap();
742
743 let _ = self.prohibit_generic_args(
744 trait_ref.path.segments.split_last().unwrap().1.iter(),
745 GenericsArgsErrExtend::None,
746 );
747 self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
748
749 let (generic_args, arg_count) = self.lower_generic_args_of_path(
750 trait_ref.path.span,
751 trait_def_id,
752 &[],
753 trait_segment,
754 Some(self_ty),
755 );
756
757 let tcx = self.tcx();
758 let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
759 debug!(?bound_vars);
760
761 let poly_trait_ref = ty::Binder::bind_with_vars(
762 ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
763 bound_vars,
764 );
765
766 debug!(?poly_trait_ref);
767
768 let polarity = match polarity {
769 rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
770 rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
771 rustc_ast::BoundPolarity::Maybe(_) => {
772 for constraint in trait_segment.args().constraints {
775 let _ = self.lower_assoc_item_constraint(
776 trait_ref.hir_ref_id,
777 poly_trait_ref,
778 constraint,
779 &mut Default::default(),
780 &mut Default::default(),
781 constraint.span,
782 predicate_filter,
783 );
784 }
785 return arg_count;
786 }
787 };
788
789 match predicate_filter {
791 PredicateFilter::All
792 | PredicateFilter::SelfOnly
793 | PredicateFilter::SelfTraitThatDefines(..)
794 | PredicateFilter::SelfAndAssociatedTypeBounds => {
795 let bound = poly_trait_ref.map_bound(|trait_ref| {
796 ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
797 });
798 let bound = (bound.upcast(tcx), span);
799 if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
801 bounds.insert(0, bound);
802 } else {
803 bounds.push(bound);
804 }
805 }
806 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
807 }
808
809 if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
810 && !self.tcx().is_const_trait(trait_def_id)
811 {
812 let (def_span, suggestion, suggestion_pre) =
813 match (trait_def_id.is_local(), self.tcx().sess.is_nightly_build()) {
814 (true, true) => (
815 None,
816 Some(tcx.def_span(trait_def_id).shrink_to_lo()),
817 if self.tcx().features().const_trait_impl() {
818 ""
819 } else {
820 "enable `#![feature(const_trait_impl)]` in your crate and "
821 },
822 ),
823 (false, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
824 };
825 self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
826 span,
827 modifier: constness.as_str(),
828 def_span,
829 trait_name: self.tcx().def_path_str(trait_def_id),
830 suggestion_pre,
831 suggestion,
832 });
833 } else {
834 match predicate_filter {
835 PredicateFilter::SelfTraitThatDefines(..) => {}
837 PredicateFilter::All
838 | PredicateFilter::SelfOnly
839 | PredicateFilter::SelfAndAssociatedTypeBounds => {
840 match constness {
841 hir::BoundConstness::Always(span) => {
842 if polarity == ty::PredicatePolarity::Positive {
843 bounds.push((
844 poly_trait_ref
845 .to_host_effect_clause(tcx, ty::BoundConstness::Const),
846 span,
847 ));
848 }
849 }
850 hir::BoundConstness::Maybe(_) => {
851 }
856 hir::BoundConstness::Never => {}
857 }
858 }
859 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
866 match constness {
867 hir::BoundConstness::Maybe(span) => {
868 if polarity == ty::PredicatePolarity::Positive {
869 bounds.push((
870 poly_trait_ref
871 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
872 span,
873 ));
874 }
875 }
876 hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
877 }
878 }
879 }
880 }
881
882 let mut dup_constraints = FxIndexMap::default();
883 for constraint in trait_segment.args().constraints {
884 if polarity != ty::PredicatePolarity::Positive {
888 self.dcx().span_delayed_bug(
889 constraint.span,
890 "negative trait bounds should not have assoc item constraints",
891 );
892 break;
893 }
894
895 let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
897 trait_ref.hir_ref_id,
898 poly_trait_ref,
899 constraint,
900 bounds,
901 &mut dup_constraints,
902 constraint.span,
903 predicate_filter,
904 );
905 }
907
908 arg_count
909 }
910
911 fn lower_mono_trait_ref(
915 &self,
916 span: Span,
917 trait_def_id: DefId,
918 self_ty: Ty<'tcx>,
919 trait_segment: &hir::PathSegment<'tcx>,
920 is_impl: bool,
921 ) -> ty::TraitRef<'tcx> {
922 self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
923
924 let (generic_args, _) =
925 self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
926 if let Some(c) = trait_segment.args().constraints.first() {
927 prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
928 }
929 ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
930 }
931
932 fn probe_trait_that_defines_assoc_item(
933 &self,
934 trait_def_id: DefId,
935 assoc_kind: ty::AssocKind,
936 assoc_name: Ident,
937 ) -> bool {
938 self.tcx()
939 .associated_items(trait_def_id)
940 .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id)
941 .is_some()
942 }
943
944 fn lower_path_segment(
945 &self,
946 span: Span,
947 did: DefId,
948 item_segment: &hir::PathSegment<'tcx>,
949 ) -> Ty<'tcx> {
950 let tcx = self.tcx();
951 let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
952
953 if let DefKind::TyAlias = tcx.def_kind(did)
954 && tcx.type_alias_is_lazy(did)
955 {
956 let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
960 Ty::new_alias(tcx, ty::Weak, alias_ty)
961 } else {
962 tcx.at(span).type_of(did).instantiate(tcx, args)
963 }
964 }
965
966 #[instrument(level = "debug", skip_all, ret)]
974 fn probe_single_ty_param_bound_for_assoc_item(
975 &self,
976 ty_param_def_id: LocalDefId,
977 ty_param_span: Span,
978 kind: ty::AssocKind,
979 assoc_name: Ident,
980 span: Span,
981 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
982 debug!(?ty_param_def_id, ?assoc_name, ?span);
983 let tcx = self.tcx();
984
985 let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name);
986 debug!("predicates={:#?}", predicates);
987
988 self.probe_single_bound_for_assoc_item(
989 || {
990 let trait_refs = predicates
991 .iter_identity_copied()
992 .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
993 traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
994 },
995 AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
996 kind,
997 assoc_name,
998 span,
999 None,
1000 )
1001 }
1002
1003 #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1008 fn probe_single_bound_for_assoc_item<I>(
1009 &self,
1010 all_candidates: impl Fn() -> I,
1011 qself: AssocItemQSelf,
1012 assoc_kind: ty::AssocKind,
1013 assoc_name: Ident,
1014 span: Span,
1015 constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1016 ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1017 where
1018 I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1019 {
1020 let tcx = self.tcx();
1021
1022 let mut matching_candidates = all_candidates().filter(|r| {
1023 self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_kind, assoc_name)
1024 });
1025
1026 let Some(bound) = matching_candidates.next() else {
1027 let reported = self.complain_about_assoc_item_not_found(
1028 all_candidates,
1029 qself,
1030 assoc_kind,
1031 assoc_name,
1032 span,
1033 constraint,
1034 );
1035 return Err(reported);
1036 };
1037 debug!(?bound);
1038
1039 if let Some(bound2) = matching_candidates.next() {
1040 debug!(?bound2);
1041
1042 let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
1043 let qself_str = qself.to_string(tcx);
1044 let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1045 span,
1046 assoc_kind: assoc_kind_str,
1047 assoc_name,
1048 qself: &qself_str,
1049 });
1050 err.code(
1052 if let Some(constraint) = constraint
1053 && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1054 {
1055 E0222
1056 } else {
1057 E0221
1058 },
1059 );
1060
1061 let mut where_bounds = vec![];
1064 for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1065 let bound_id = bound.def_id();
1066 let bound_span = tcx
1067 .associated_items(bound_id)
1068 .find_by_name_and_kind(tcx, assoc_name, assoc_kind, bound_id)
1069 .and_then(|item| tcx.hir().span_if_local(item.def_id));
1070
1071 if let Some(bound_span) = bound_span {
1072 err.span_label(
1073 bound_span,
1074 format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
1075 );
1076 if let Some(constraint) = constraint {
1077 match constraint.kind {
1078 hir::AssocItemConstraintKind::Equality { term } => {
1079 let term: ty::Term<'_> = match term {
1080 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1081 hir::Term::Const(ct) => {
1082 self.lower_const_arg(ct, FeedConstTy::No).into()
1083 }
1084 };
1085 if term.references_error() {
1086 continue;
1087 }
1088 where_bounds.push(format!(
1090 " T: {trait}::{assoc_name} = {term}",
1091 trait = bound.print_only_trait_path(),
1092 ));
1093 }
1094 hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1096 }
1097 } else {
1098 err.span_suggestion_verbose(
1099 span.with_hi(assoc_name.span.lo()),
1100 "use fully-qualified syntax to disambiguate",
1101 format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1102 Applicability::MaybeIncorrect,
1103 );
1104 }
1105 } else {
1106 err.note(format!(
1107 "associated {assoc_kind_str} `{assoc_name}` could derive from `{}`",
1108 bound.print_only_trait_path(),
1109 ));
1110 }
1111 }
1112 if !where_bounds.is_empty() {
1113 err.help(format!(
1114 "consider introducing a new type parameter `T` and adding `where` constraints:\
1115 \n where\n T: {qself_str},\n{}",
1116 where_bounds.join(",\n"),
1117 ));
1118 let reported = err.emit();
1119 return Err(reported);
1120 }
1121 err.emit();
1122 }
1123
1124 Ok(bound)
1125 }
1126
1127 #[instrument(level = "debug", skip_all, ret)]
1155 pub fn lower_assoc_path_ty(
1156 &self,
1157 hir_ref_id: HirId,
1158 span: Span,
1159 qself_ty: Ty<'tcx>,
1160 qself: &'tcx hir::Ty<'tcx>,
1161 assoc_segment: &'tcx hir::PathSegment<'tcx>,
1162 permit_variants: bool,
1163 ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1164 let tcx = self.tcx();
1165 match self.lower_assoc_path_shared(
1166 hir_ref_id,
1167 span,
1168 qself_ty,
1169 qself,
1170 assoc_segment,
1171 LowerAssocMode::Type { permit_variants },
1172 )? {
1173 LoweredAssoc::Term(def_id, args) => {
1174 let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1175 let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1176 Ok((ty, tcx.def_kind(def_id), def_id))
1177 }
1178 LoweredAssoc::Variant { adt, variant_did } => Ok((adt, DefKind::Variant, variant_did)),
1179 }
1180 }
1181
1182 #[instrument(level = "debug", skip_all, ret)]
1183 fn lower_assoc_path_const(
1184 &self,
1185 hir_ref_id: HirId,
1186 span: Span,
1187 qself_ty: Ty<'tcx>,
1188 qself: &'tcx hir::Ty<'tcx>,
1189 assoc_segment: &'tcx hir::PathSegment<'tcx>,
1190 ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1191 let tcx = self.tcx();
1192 let (def_id, args) = match self.lower_assoc_path_shared(
1193 hir_ref_id,
1194 span,
1195 qself_ty,
1196 qself,
1197 assoc_segment,
1198 LowerAssocMode::Const,
1199 )? {
1200 LoweredAssoc::Term(def_id, args) => {
1201 if !tcx.associated_item(def_id).is_type_const_capable(tcx) {
1202 let mut err = tcx.dcx().struct_span_err(
1203 span,
1204 "use of trait associated const without `#[type_const]`",
1205 );
1206 err.note("the declaration in the trait must be marked with `#[type_const]`");
1207 return Err(err.emit());
1208 }
1209 (def_id, args)
1210 }
1211 LoweredAssoc::Variant { .. } => {
1214 span_bug!(span, "unexpected variant res for type associated const path")
1215 }
1216 };
1217 Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
1218 }
1219
1220 #[instrument(level = "debug", skip_all, ret)]
1221 fn lower_assoc_path_shared(
1222 &self,
1223 hir_ref_id: HirId,
1224 span: Span,
1225 qself_ty: Ty<'tcx>,
1226 qself: &'tcx hir::Ty<'tcx>,
1227 assoc_segment: &'tcx hir::PathSegment<'tcx>,
1228 mode: LowerAssocMode,
1229 ) -> Result<LoweredAssoc<'tcx>, ErrorGuaranteed> {
1230 debug!(%qself_ty, ?assoc_segment.ident);
1231 let tcx = self.tcx();
1232
1233 let assoc_ident = assoc_segment.ident;
1234
1235 let mut variant_resolution = None;
1237 if let Some(adt_def) = self.probe_adt(span, qself_ty) {
1238 if adt_def.is_enum() {
1239 let variant_def = adt_def
1240 .variants()
1241 .iter()
1242 .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
1243 if let Some(variant_def) = variant_def {
1244 if mode.permit_variants() {
1245 tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
1246 let _ = self.prohibit_generic_args(
1247 slice::from_ref(assoc_segment).iter(),
1248 GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def },
1249 );
1250 return Ok(LoweredAssoc::Variant {
1251 adt: qself_ty,
1252 variant_did: variant_def.def_id,
1253 });
1254 } else {
1255 variant_resolution = Some(variant_def.def_id);
1256 }
1257 }
1258 }
1259
1260 if let Some((did, args)) = self.probe_inherent_assoc_shared(
1262 assoc_segment,
1263 adt_def.did(),
1264 qself_ty,
1265 hir_ref_id,
1266 span,
1267 mode.kind(),
1268 )? {
1269 return Ok(LoweredAssoc::Term(did, args));
1270 }
1271 }
1272
1273 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
1274 path.res
1275 } else {
1276 Res::Err
1277 };
1278
1279 let bound = match (qself_ty.kind(), qself_res) {
1282 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1283 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1286 self.dcx().span_bug(span, "expected cycle error");
1288 };
1289
1290 self.probe_single_bound_for_assoc_item(
1291 || {
1292 traits::supertraits(
1293 tcx,
1294 ty::Binder::dummy(trait_ref.instantiate_identity()),
1295 )
1296 },
1297 AssocItemQSelf::SelfTyAlias,
1298 mode.kind(),
1299 assoc_ident,
1300 span,
1301 None,
1302 )?
1303 }
1304 (
1305 &ty::Param(_),
1306 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1307 ) => self.probe_single_ty_param_bound_for_assoc_item(
1308 param_did.expect_local(),
1309 qself.span,
1310 mode.kind(),
1311 assoc_ident,
1312 span,
1313 )?,
1314 _ => {
1315 let kind_str = assoc_kind_str(mode.kind());
1316 let reported = if variant_resolution.is_some() {
1317 let msg = format!("expected {kind_str}, found variant `{assoc_ident}`");
1319 self.dcx().span_err(span, msg)
1320 } else if qself_ty.is_enum() {
1321 let mut err = self.dcx().create_err(NoVariantNamed {
1322 span: assoc_ident.span,
1323 ident: assoc_ident,
1324 ty: qself_ty,
1325 });
1326
1327 let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
1328 if let Some(variant_name) = find_best_match_for_name(
1329 &adt_def
1330 .variants()
1331 .iter()
1332 .map(|variant| variant.name)
1333 .collect::<Vec<Symbol>>(),
1334 assoc_ident.name,
1335 None,
1336 ) && let Some(variant) =
1337 adt_def.variants().iter().find(|s| s.name == variant_name)
1338 {
1339 let mut suggestion = vec![(assoc_ident.span, variant_name.to_string())];
1340 if let hir::Node::Stmt(&hir::Stmt {
1341 kind: hir::StmtKind::Semi(expr), ..
1342 })
1343 | hir::Node::Expr(expr) = tcx.parent_hir_node(hir_ref_id)
1344 && let hir::ExprKind::Struct(..) = expr.kind
1345 {
1346 match variant.ctor {
1347 None => {
1348 suggestion = vec![(
1350 assoc_ident.span.with_hi(expr.span.hi()),
1351 if variant.fields.is_empty() {
1352 format!("{variant_name} {{}}")
1353 } else {
1354 format!(
1355 "{variant_name} {{ {} }}",
1356 variant
1357 .fields
1358 .iter()
1359 .map(|f| format!("{}: /* value */", f.name))
1360 .collect::<Vec<_>>()
1361 .join(", ")
1362 )
1363 },
1364 )];
1365 }
1366 Some((hir::def::CtorKind::Fn, def_id)) => {
1367 let fn_sig = tcx.fn_sig(def_id).instantiate_identity();
1369 let inputs = fn_sig.inputs().skip_binder();
1370 suggestion = vec![(
1371 assoc_ident.span.with_hi(expr.span.hi()),
1372 format!(
1373 "{variant_name}({})",
1374 inputs
1375 .iter()
1376 .map(|i| format!("/* {i} */"))
1377 .collect::<Vec<_>>()
1378 .join(", ")
1379 ),
1380 )];
1381 }
1382 Some((hir::def::CtorKind::Const, _)) => {
1383 suggestion = vec![(
1385 assoc_ident.span.with_hi(expr.span.hi()),
1386 variant_name.to_string(),
1387 )];
1388 }
1389 }
1390 }
1391 err.multipart_suggestion_verbose(
1392 "there is a variant with a similar name",
1393 suggestion,
1394 Applicability::HasPlaceholders,
1395 );
1396 } else {
1397 err.span_label(
1398 assoc_ident.span,
1399 format!("variant not found in `{qself_ty}`"),
1400 );
1401 }
1402
1403 if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
1404 err.span_label(sp, format!("variant `{assoc_ident}` not found here"));
1405 }
1406
1407 err.emit()
1408 } else if let Err(reported) = qself_ty.error_reported() {
1409 reported
1410 } else {
1411 self.maybe_report_similar_assoc_fn(span, qself_ty, qself)?;
1412
1413 let traits: Vec<_> =
1414 self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
1415
1416 self.report_ambiguous_assoc(
1418 span,
1419 &[qself_ty.to_string()],
1420 &traits,
1421 assoc_ident.name,
1422 mode.kind(),
1423 )
1424 };
1425 return Err(reported);
1426 }
1427 };
1428
1429 let trait_did = bound.def_id();
1430 let assoc_item = self
1431 .probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did)
1432 .expect("failed to find associated item");
1433 let (def_id, args) =
1434 self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?;
1435 let result = LoweredAssoc::Term(def_id, args);
1436
1437 if let Some(variant_def_id) = variant_resolution {
1438 tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
1439 lint.primary_message("ambiguous associated item");
1440 let mut could_refer_to = |kind: DefKind, def_id, also| {
1441 let note_msg = format!(
1442 "`{}` could{} refer to the {} defined here",
1443 assoc_ident,
1444 also,
1445 tcx.def_kind_descr(kind, def_id)
1446 );
1447 lint.span_note(tcx.def_span(def_id), note_msg);
1448 };
1449
1450 could_refer_to(DefKind::Variant, variant_def_id, "");
1451 could_refer_to(mode.def_kind(), assoc_item.def_id, " also");
1452
1453 lint.span_suggestion(
1454 span,
1455 "use fully-qualified syntax",
1456 format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
1457 Applicability::MachineApplicable,
1458 );
1459 });
1460 }
1461 Ok(result)
1462 }
1463
1464 fn probe_inherent_assoc_shared(
1465 &self,
1466 segment: &hir::PathSegment<'tcx>,
1467 adt_did: DefId,
1468 self_ty: Ty<'tcx>,
1469 block: HirId,
1470 span: Span,
1471 kind: ty::AssocKind,
1472 ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1473 let tcx = self.tcx();
1474
1475 if !tcx.features().inherent_associated_types() {
1476 match kind {
1477 ty::AssocKind::Type => return Ok(None),
1484 ty::AssocKind::Const => {
1485 return Err(feature_err(
1489 &tcx.sess,
1490 sym::inherent_associated_types,
1491 span,
1492 "inherent associated types are unstable",
1493 )
1494 .emit());
1495 }
1496 ty::AssocKind::Fn => unreachable!(),
1497 }
1498 }
1499
1500 let name = segment.ident;
1501 let candidates: Vec<_> = tcx
1502 .inherent_impls(adt_did)
1503 .iter()
1504 .filter_map(|&impl_| {
1505 let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?;
1506 Some((impl_, (item.def_id, scope)))
1507 })
1508 .collect();
1509
1510 if candidates.is_empty() {
1511 return Ok(None);
1512 }
1513
1514 let infcx = match self.infcx() {
1521 Some(infcx) => infcx,
1522 None => {
1523 assert!(!self_ty.has_infer());
1524 &tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis())
1525 }
1526 };
1527
1528 let param_env = tcx.param_env(block.owner);
1531
1532 let mut universes = if self_ty.has_escaping_bound_vars() {
1533 vec![None; self_ty.outer_exclusive_binder().as_usize()]
1534 } else {
1535 vec![]
1536 };
1537
1538 let (impl_, (assoc_item, def_scope)) = crate::traits::with_replaced_escaping_bound_vars(
1539 infcx,
1540 &mut universes,
1541 self_ty,
1542 |self_ty| {
1543 self.select_inherent_assoc_candidates(
1544 infcx, name, span, self_ty, param_env, candidates, kind,
1545 )
1546 },
1547 )?;
1548
1549 self.check_assoc_item(assoc_item, name, def_scope, block, span);
1550
1551 let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1555 let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1556 let args = tcx.mk_args_from_iter(
1557 std::iter::once(ty::GenericArg::from(self_ty))
1558 .chain(args.into_iter().skip(parent_args.len())),
1559 );
1560
1561 Ok(Some((assoc_item, args)))
1562 }
1563
1564 fn select_inherent_assoc_candidates(
1565 &self,
1566 infcx: &InferCtxt<'tcx>,
1567 name: Ident,
1568 span: Span,
1569 self_ty: Ty<'tcx>,
1570 param_env: ParamEnv<'tcx>,
1571 candidates: Vec<(DefId, (DefId, DefId))>,
1572 kind: ty::AssocKind,
1573 ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
1574 let tcx = self.tcx();
1575 let mut fulfillment_errors = Vec::new();
1576
1577 let applicable_candidates: Vec<_> = candidates
1578 .iter()
1579 .copied()
1580 .filter(|&(impl_, _)| {
1581 infcx.probe(|_| {
1582 let ocx = ObligationCtxt::new_with_diagnostics(infcx);
1583 let self_ty = ocx.normalize(&ObligationCause::dummy(), param_env, self_ty);
1584
1585 let impl_args = infcx.fresh_args_for_item(span, impl_);
1586 let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args);
1587 let impl_ty = ocx.normalize(&ObligationCause::dummy(), param_env, impl_ty);
1588
1589 if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
1591 return false;
1592 }
1593
1594 let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args);
1596 let impl_bounds =
1597 ocx.normalize(&ObligationCause::dummy(), param_env, impl_bounds);
1598 let impl_obligations = traits::predicates_for_generics(
1599 |_, _| ObligationCause::dummy(),
1600 param_env,
1601 impl_bounds,
1602 );
1603 ocx.register_obligations(impl_obligations);
1604
1605 let mut errors = ocx.select_where_possible();
1606 if !errors.is_empty() {
1607 fulfillment_errors.append(&mut errors);
1608 return false;
1609 }
1610
1611 true
1612 })
1613 })
1614 .collect();
1615
1616 match &applicable_candidates[..] {
1617 &[] => Err(self.complain_about_inherent_assoc_not_found(
1618 name,
1619 self_ty,
1620 candidates,
1621 fulfillment_errors,
1622 span,
1623 kind,
1624 )),
1625
1626 &[applicable_candidate] => Ok(applicable_candidate),
1627
1628 &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc(
1629 name,
1630 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1631 span,
1632 )),
1633 }
1634 }
1635
1636 fn probe_assoc_item(
1640 &self,
1641 ident: Ident,
1642 kind: ty::AssocKind,
1643 block: HirId,
1644 span: Span,
1645 scope: DefId,
1646 ) -> Option<ty::AssocItem> {
1647 let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?;
1648 self.check_assoc_item(item.def_id, ident, scope, block, span);
1649 Some(item)
1650 }
1651
1652 fn probe_assoc_item_unchecked(
1657 &self,
1658 ident: Ident,
1659 kind: ty::AssocKind,
1660 block: HirId,
1661 scope: DefId,
1662 ) -> Option<(ty::AssocItem, DefId)> {
1663 let tcx = self.tcx();
1664
1665 let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1666 let item = tcx
1670 .associated_items(scope)
1671 .filter_by_name_unhygienic(ident.name)
1672 .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1673
1674 Some((*item, def_scope))
1675 }
1676
1677 fn check_assoc_item(
1679 &self,
1680 item_def_id: DefId,
1681 ident: Ident,
1682 scope: DefId,
1683 block: HirId,
1684 span: Span,
1685 ) {
1686 let tcx = self.tcx();
1687
1688 if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1689 self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1690 span,
1691 kind: tcx.def_descr(item_def_id),
1692 name: ident,
1693 defined_here_label: tcx.def_span(item_def_id),
1694 });
1695 }
1696
1697 tcx.check_stability(item_def_id, Some(block), span, None);
1698 }
1699
1700 fn probe_traits_that_match_assoc_ty(
1701 &self,
1702 qself_ty: Ty<'tcx>,
1703 assoc_ident: Ident,
1704 ) -> Vec<String> {
1705 let tcx = self.tcx();
1706
1707 let infcx_;
1710 let infcx = if let Some(infcx) = self.infcx() {
1711 infcx
1712 } else {
1713 assert!(!qself_ty.has_infer());
1714 infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1715 &infcx_
1716 };
1717
1718 tcx.all_traits()
1719 .filter(|trait_def_id| {
1720 tcx.associated_items(*trait_def_id)
1722 .in_definition_order()
1723 .any(|i| {
1724 i.kind.namespace() == Namespace::TypeNS
1725 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1726 && matches!(i.kind, ty::AssocKind::Type)
1727 })
1728 && tcx.visibility(*trait_def_id)
1730 .is_accessible_from(self.item_def_id(), tcx)
1731 && tcx.all_impls(*trait_def_id)
1732 .any(|impl_def_id| {
1733 let impl_header = tcx.impl_trait_header(impl_def_id);
1734 impl_header.is_some_and(|header| {
1735 let trait_ref = header.trait_ref.instantiate(
1736 tcx,
1737 infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1738 );
1739
1740 let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1741 if value.has_escaping_bound_vars() {
1743 return false;
1744 }
1745 infcx
1746 .can_eq(
1747 ty::ParamEnv::empty(),
1748 trait_ref.self_ty(),
1749 value,
1750 ) && header.polarity != ty::ImplPolarity::Negative
1751 })
1752 })
1753 })
1754 .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1755 .collect()
1756 }
1757
1758 #[instrument(level = "debug", skip_all)]
1760 fn lower_qpath_ty(
1761 &self,
1762 span: Span,
1763 opt_self_ty: Option<Ty<'tcx>>,
1764 item_def_id: DefId,
1765 trait_segment: &hir::PathSegment<'tcx>,
1766 item_segment: &hir::PathSegment<'tcx>,
1767 ) -> Ty<'tcx> {
1768 match self.lower_qpath_shared(
1769 span,
1770 opt_self_ty,
1771 item_def_id,
1772 trait_segment,
1773 item_segment,
1774 ty::AssocKind::Type,
1775 ) {
1776 Ok((item_def_id, item_args)) => {
1777 Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1778 }
1779 Err(guar) => Ty::new_error(self.tcx(), guar),
1780 }
1781 }
1782
1783 #[instrument(level = "debug", skip_all)]
1785 fn lower_qpath_const(
1786 &self,
1787 span: Span,
1788 opt_self_ty: Option<Ty<'tcx>>,
1789 item_def_id: DefId,
1790 trait_segment: &hir::PathSegment<'tcx>,
1791 item_segment: &hir::PathSegment<'tcx>,
1792 ) -> Const<'tcx> {
1793 match self.lower_qpath_shared(
1794 span,
1795 opt_self_ty,
1796 item_def_id,
1797 trait_segment,
1798 item_segment,
1799 ty::AssocKind::Const,
1800 ) {
1801 Ok((item_def_id, item_args)) => {
1802 let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1803 Const::new_unevaluated(self.tcx(), uv)
1804 }
1805 Err(guar) => Const::new_error(self.tcx(), guar),
1806 }
1807 }
1808
1809 #[instrument(level = "debug", skip_all)]
1810 fn lower_qpath_shared(
1811 &self,
1812 span: Span,
1813 opt_self_ty: Option<Ty<'tcx>>,
1814 item_def_id: DefId,
1815 trait_segment: &hir::PathSegment<'tcx>,
1816 item_segment: &hir::PathSegment<'tcx>,
1817 kind: ty::AssocKind,
1818 ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1819 let tcx = self.tcx();
1820
1821 let trait_def_id = tcx.parent(item_def_id);
1822 debug!(?trait_def_id);
1823
1824 let Some(self_ty) = opt_self_ty else {
1825 return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind));
1826 };
1827 debug!(?self_ty);
1828
1829 let trait_ref =
1830 self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
1831 debug!(?trait_ref);
1832
1833 let item_args =
1834 self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1835
1836 Ok((item_def_id, item_args))
1837 }
1838
1839 fn error_missing_qpath_self_ty(
1840 &self,
1841 trait_def_id: DefId,
1842 span: Span,
1843 item_segment: &hir::PathSegment<'tcx>,
1844 kind: ty::AssocKind,
1845 ) -> ErrorGuaranteed {
1846 let tcx = self.tcx();
1847 let path_str = tcx.def_path_str(trait_def_id);
1848
1849 let def_id = self.item_def_id();
1850 debug!(item_def_id = ?def_id);
1851
1852 let parent_def_id = tcx.hir_get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
1854 debug!(?parent_def_id);
1855
1856 let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
1859 let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
1860
1861 let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
1862 vec!["Self".to_string()]
1863 } else {
1864 tcx.all_impls(trait_def_id)
1866 .filter_map(|impl_def_id| tcx.impl_trait_header(impl_def_id))
1867 .filter(|header| {
1868 tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1870 && header.polarity != ty::ImplPolarity::Negative
1871 })
1872 .map(|header| header.trait_ref.instantiate_identity().self_ty())
1873 .filter(|self_ty| !self_ty.has_non_region_param())
1875 .map(|self_ty| tcx.erase_regions(self_ty).to_string())
1876 .collect()
1877 };
1878 self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind)
1882 }
1883
1884 pub fn prohibit_generic_args<'a>(
1885 &self,
1886 segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1887 err_extend: GenericsArgsErrExtend<'a>,
1888 ) -> Result<(), ErrorGuaranteed> {
1889 let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1890 let mut result = Ok(());
1891 if let Some(_) = args_visitors.clone().next() {
1892 result = Err(self.report_prohibit_generics_error(
1893 segments.clone(),
1894 args_visitors,
1895 err_extend,
1896 ));
1897 }
1898
1899 for segment in segments {
1900 if let Some(c) = segment.args().constraints.first() {
1902 return Err(prohibit_assoc_item_constraint(self, c, None));
1903 }
1904 }
1905
1906 result
1907 }
1908
1909 pub fn probe_generic_path_segments(
1927 &self,
1928 segments: &[hir::PathSegment<'_>],
1929 self_ty: Option<Ty<'tcx>>,
1930 kind: DefKind,
1931 def_id: DefId,
1932 span: Span,
1933 ) -> Vec<GenericPathSegment> {
1934 let tcx = self.tcx();
1980
1981 assert!(!segments.is_empty());
1982 let last = segments.len() - 1;
1983
1984 let mut generic_segments = vec![];
1985
1986 match kind {
1987 DefKind::Ctor(CtorOf::Struct, ..) => {
1989 let generics = tcx.generics_of(def_id);
1992 let generics_def_id = generics.parent.unwrap_or(def_id);
1995 generic_segments.push(GenericPathSegment(generics_def_id, last));
1996 }
1997
1998 DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
2000 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
2001 let adt_def = self.probe_adt(span, self_ty).unwrap();
2002 debug_assert!(adt_def.is_enum());
2003 (adt_def.did(), last)
2004 } else if last >= 1 && segments[last - 1].args.is_some() {
2005 let mut def_id = def_id;
2008
2009 if let DefKind::Ctor(..) = kind {
2011 def_id = tcx.parent(def_id);
2012 }
2013
2014 let enum_def_id = tcx.parent(def_id);
2016 (enum_def_id, last - 1)
2017 } else {
2018 let generics = tcx.generics_of(def_id);
2024 (generics.parent.unwrap_or(def_id), last)
2027 };
2028 generic_segments.push(GenericPathSegment(generics_def_id, index));
2029 }
2030
2031 DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
2033 generic_segments.push(GenericPathSegment(def_id, last));
2034 }
2035
2036 DefKind::AssocFn | DefKind::AssocConst => {
2038 if segments.len() >= 2 {
2039 let generics = tcx.generics_of(def_id);
2040 generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
2041 }
2042 generic_segments.push(GenericPathSegment(def_id, last));
2043 }
2044
2045 kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
2046 }
2047
2048 debug!(?generic_segments);
2049
2050 generic_segments
2051 }
2052
2053 #[instrument(level = "debug", skip_all)]
2055 pub fn lower_path(
2056 &self,
2057 opt_self_ty: Option<Ty<'tcx>>,
2058 path: &hir::Path<'tcx>,
2059 hir_id: HirId,
2060 permit_variants: bool,
2061 ) -> Ty<'tcx> {
2062 debug!(?path.res, ?opt_self_ty, ?path.segments);
2063 let tcx = self.tcx();
2064
2065 let span = path.span;
2066 match path.res {
2067 Res::Def(DefKind::OpaqueTy, did) => {
2068 assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
2070 let item_segment = path.segments.split_last().unwrap();
2071 let _ = self
2072 .prohibit_generic_args(item_segment.1.iter(), GenericsArgsErrExtend::OpaqueTy);
2073 let args = self.lower_generic_args_of_path_segment(span, did, item_segment.0);
2074 Ty::new_opaque(tcx, did, args)
2075 }
2076 Res::Def(
2077 DefKind::Enum
2078 | DefKind::TyAlias
2079 | DefKind::Struct
2080 | DefKind::Union
2081 | DefKind::ForeignTy,
2082 did,
2083 ) => {
2084 assert_eq!(opt_self_ty, None);
2085 let _ = self.prohibit_generic_args(
2086 path.segments.split_last().unwrap().1.iter(),
2087 GenericsArgsErrExtend::None,
2088 );
2089 self.lower_path_segment(span, did, path.segments.last().unwrap())
2090 }
2091 Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
2092 assert_eq!(opt_self_ty, None);
2095
2096 let generic_segments =
2097 self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
2098 let indices: FxHashSet<_> =
2099 generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
2100 let _ = self.prohibit_generic_args(
2101 path.segments.iter().enumerate().filter_map(|(index, seg)| {
2102 if !indices.contains(&index) { Some(seg) } else { None }
2103 }),
2104 GenericsArgsErrExtend::DefVariant(&path.segments),
2105 );
2106
2107 let GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
2108 self.lower_path_segment(span, *def_id, &path.segments[*index])
2109 }
2110 Res::Def(DefKind::TyParam, def_id) => {
2111 assert_eq!(opt_self_ty, None);
2112 let _ = self.prohibit_generic_args(
2113 path.segments.iter(),
2114 GenericsArgsErrExtend::Param(def_id),
2115 );
2116 self.lower_ty_param(hir_id)
2117 }
2118 Res::SelfTyParam { .. } => {
2119 assert_eq!(opt_self_ty, None);
2121 let _ = self.prohibit_generic_args(
2122 path.segments.iter(),
2123 if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2124 GenericsArgsErrExtend::SelfTyParam(
2125 ident.span.shrink_to_hi().to(args.span_ext),
2126 )
2127 } else {
2128 GenericsArgsErrExtend::None
2129 },
2130 );
2131 tcx.types.self_param
2132 }
2133 Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
2134 assert_eq!(opt_self_ty, None);
2136 let ty = tcx.at(span).type_of(def_id).instantiate_identity();
2138 let _ = self.prohibit_generic_args(
2139 path.segments.iter(),
2140 GenericsArgsErrExtend::SelfTyAlias { def_id, span },
2141 );
2142 if forbid_generic && ty.has_param() {
2162 let mut err = self.dcx().struct_span_err(
2163 path.span,
2164 "generic `Self` types are currently not permitted in anonymous constants",
2165 );
2166 if let Some(hir::Node::Item(&hir::Item {
2167 kind: hir::ItemKind::Impl(impl_),
2168 ..
2169 })) = tcx.hir_get_if_local(def_id)
2170 {
2171 err.span_note(impl_.self_ty.span, "not a concrete type");
2172 }
2173 let reported = err.emit();
2174 Ty::new_error(tcx, reported)
2175 } else {
2176 ty
2177 }
2178 }
2179 Res::Def(DefKind::AssocTy, def_id) => {
2180 debug_assert!(path.segments.len() >= 2);
2181 let _ = self.prohibit_generic_args(
2182 path.segments[..path.segments.len() - 2].iter(),
2183 GenericsArgsErrExtend::None,
2184 );
2185 self.lower_qpath_ty(
2186 span,
2187 opt_self_ty,
2188 def_id,
2189 &path.segments[path.segments.len() - 2],
2190 path.segments.last().unwrap(),
2191 )
2192 }
2193 Res::PrimTy(prim_ty) => {
2194 assert_eq!(opt_self_ty, None);
2195 let _ = self.prohibit_generic_args(
2196 path.segments.iter(),
2197 GenericsArgsErrExtend::PrimTy(prim_ty),
2198 );
2199 match prim_ty {
2200 hir::PrimTy::Bool => tcx.types.bool,
2201 hir::PrimTy::Char => tcx.types.char,
2202 hir::PrimTy::Int(it) => Ty::new_int(tcx, ty::int_ty(it)),
2203 hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, ty::uint_ty(uit)),
2204 hir::PrimTy::Float(ft) => Ty::new_float(tcx, ty::float_ty(ft)),
2205 hir::PrimTy::Str => tcx.types.str_,
2206 }
2207 }
2208 Res::Err => {
2209 let e = self
2210 .tcx()
2211 .dcx()
2212 .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2213 Ty::new_error(tcx, e)
2214 }
2215 Res::Def(..) => {
2216 assert_eq!(
2217 path.segments.get(0).map(|seg| seg.ident.name),
2218 Some(kw::SelfUpper),
2219 "only expected incorrect resolution for `Self`"
2220 );
2221 Ty::new_error(
2222 self.tcx(),
2223 self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2224 )
2225 }
2226 _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2227 }
2228 }
2229
2230 pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2235 let tcx = self.tcx();
2236 match tcx.named_bound_var(hir_id) {
2237 Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2238 let name = tcx.item_name(def_id.to_def_id());
2239 let br = ty::BoundTy {
2240 var: ty::BoundVar::from_u32(index),
2241 kind: ty::BoundTyKind::Param(def_id.to_def_id(), name),
2242 };
2243 Ty::new_bound(tcx, debruijn, br)
2244 }
2245 Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2246 let item_def_id = tcx.hir_ty_param_owner(def_id);
2247 let generics = tcx.generics_of(item_def_id);
2248 let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2249 Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2250 }
2251 Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2252 arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2253 }
2254 }
2255
2256 pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2261 let tcx = self.tcx();
2262
2263 match tcx.named_bound_var(path_hir_id) {
2264 Some(rbv::ResolvedArg::EarlyBound(_)) => {
2265 let item_def_id = tcx.parent(param_def_id);
2268 let generics = tcx.generics_of(item_def_id);
2269 let index = generics.param_def_id_to_index[¶m_def_id];
2270 let name = tcx.item_name(param_def_id);
2271 ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2272 }
2273 Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2274 ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
2275 }
2276 Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2277 arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2278 }
2279 }
2280
2281 #[instrument(skip(self), level = "debug")]
2283 pub fn lower_const_arg(
2284 &self,
2285 const_arg: &hir::ConstArg<'tcx>,
2286 feed: FeedConstTy<'_, 'tcx>,
2287 ) -> Const<'tcx> {
2288 let tcx = self.tcx();
2289
2290 if let FeedConstTy::Param(param_def_id, args) = feed
2291 && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2292 {
2293 let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
2294
2295 if tcx.features().generic_const_parameter_types()
2304 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2305 {
2306 let e = tcx.dcx().span_err(
2307 const_arg.span(),
2308 "anonymous constants with lifetimes in their type are not yet supported",
2309 );
2310 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2311 return ty::Const::new_error(tcx, e);
2312 }
2313 if anon_const_type.has_non_region_infer() {
2317 let e = tcx.dcx().span_err(
2318 const_arg.span(),
2319 "anonymous constants with inferred types are not yet supported",
2320 );
2321 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2322 return ty::Const::new_error(tcx, e);
2323 }
2324 if anon_const_type.has_non_region_param() {
2327 let e = tcx.dcx().span_err(
2328 const_arg.span(),
2329 "anonymous constants referencing generics are not yet supported",
2330 );
2331 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2332 return ty::Const::new_error(tcx, e);
2333 }
2334
2335 tcx.feed_anon_const_type(
2336 anon.def_id,
2337 ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
2338 );
2339 }
2340
2341 let hir_id = const_arg.hir_id;
2342 match const_arg.kind {
2343 hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2344 debug!(?maybe_qself, ?path);
2345 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2346 self.lower_const_path_resolved(opt_self_ty, path, hir_id)
2347 }
2348 hir::ConstArgKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
2349 debug!(?qself, ?segment);
2350 let ty = self.lower_ty(qself);
2351 self.lower_assoc_path_const(hir_id, const_arg.span(), ty, qself, segment)
2352 .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2353 }
2354 hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
2355 ty::Const::new_error_with_message(
2356 tcx,
2357 qpath.span(),
2358 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
2359 )
2360 }
2361 hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
2362 hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
2363 }
2364 }
2365
2366 fn lower_const_path_resolved(
2367 &self,
2368 opt_self_ty: Option<Ty<'tcx>>,
2369 path: &hir::Path<'tcx>,
2370 hir_id: HirId,
2371 ) -> Const<'tcx> {
2372 let tcx = self.tcx();
2373 let span = path.span;
2374 match path.res {
2375 Res::Def(DefKind::ConstParam, def_id) => {
2376 assert_eq!(opt_self_ty, None);
2377 let _ = self.prohibit_generic_args(
2378 path.segments.iter(),
2379 GenericsArgsErrExtend::Param(def_id),
2380 );
2381 self.lower_const_param(def_id, hir_id)
2382 }
2383 Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
2384 assert_eq!(opt_self_ty, None);
2385 let _ = self.prohibit_generic_args(
2386 path.segments.split_last().unwrap().1.iter(),
2387 GenericsArgsErrExtend::None,
2388 );
2389 let args = self.lower_generic_args_of_path_segment(
2390 span,
2391 did,
2392 path.segments.last().unwrap(),
2393 );
2394 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2395 }
2396 Res::Def(DefKind::AssocConst, did) => {
2397 debug_assert!(path.segments.len() >= 2);
2398 let _ = self.prohibit_generic_args(
2399 path.segments[..path.segments.len() - 2].iter(),
2400 GenericsArgsErrExtend::None,
2401 );
2402 self.lower_qpath_const(
2403 span,
2404 opt_self_ty,
2405 did,
2406 &path.segments[path.segments.len() - 2],
2407 path.segments.last().unwrap(),
2408 )
2409 }
2410 Res::Def(DefKind::Static { .. }, _) => {
2411 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2412 }
2413 Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2415 self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2416 let args = self.lower_generic_args_of_path_segment(
2417 span,
2418 did,
2419 path.segments.last().unwrap(),
2420 );
2421 ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2422 }
2423
2424 res @ (Res::Def(
2427 DefKind::Mod
2428 | DefKind::Enum
2429 | DefKind::Variant
2430 | DefKind::Ctor(CtorOf::Variant, CtorKind::Fn)
2431 | DefKind::Struct
2432 | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
2433 | DefKind::OpaqueTy
2434 | DefKind::TyAlias
2435 | DefKind::TraitAlias
2436 | DefKind::AssocTy
2437 | DefKind::Union
2438 | DefKind::Trait
2439 | DefKind::ForeignTy
2440 | DefKind::TyParam
2441 | DefKind::Macro(_)
2442 | DefKind::LifetimeParam
2443 | DefKind::Use
2444 | DefKind::ForeignMod
2445 | DefKind::AnonConst
2446 | DefKind::InlineConst
2447 | DefKind::Field
2448 | DefKind::Impl { .. }
2449 | DefKind::Closure
2450 | DefKind::ExternCrate
2451 | DefKind::GlobalAsm
2452 | DefKind::SyntheticCoroutineBody,
2453 _,
2454 )
2455 | Res::PrimTy(_)
2456 | Res::SelfTyParam { .. }
2457 | Res::SelfTyAlias { .. }
2458 | Res::SelfCtor(_)
2459 | Res::Local(_)
2460 | Res::ToolMod
2461 | Res::NonMacroAttr(_)
2462 | Res::Err) => Const::new_error_with_message(
2463 tcx,
2464 span,
2465 format!("invalid Res {res:?} for const path"),
2466 ),
2467 }
2468 }
2469
2470 #[instrument(skip(self), level = "debug")]
2472 fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
2473 let tcx = self.tcx();
2474
2475 let expr = &tcx.hir_body(anon.body).value;
2476 debug!(?expr);
2477
2478 let ty = tcx.type_of(anon.def_id).instantiate_identity();
2482
2483 match self.try_lower_anon_const_lit(ty, expr) {
2484 Some(v) => v,
2485 None => ty::Const::new_unevaluated(
2486 tcx,
2487 ty::UnevaluatedConst {
2488 def: anon.def_id.to_def_id(),
2489 args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2490 },
2491 ),
2492 }
2493 }
2494
2495 #[instrument(skip(self), level = "debug")]
2496 fn try_lower_anon_const_lit(
2497 &self,
2498 ty: Ty<'tcx>,
2499 expr: &'tcx hir::Expr<'tcx>,
2500 ) -> Option<Const<'tcx>> {
2501 let tcx = self.tcx();
2502
2503 let expr = match &expr.kind {
2506 hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2507 block.expr.as_ref().unwrap()
2508 }
2509 _ => expr,
2510 };
2511
2512 if let hir::ExprKind::Path(hir::QPath::Resolved(
2513 _,
2514 &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
2515 )) = expr.kind
2516 {
2517 span_bug!(
2518 expr.span,
2519 "try_lower_anon_const_lit: received const param which shouldn't be possible"
2520 );
2521 };
2522
2523 let lit_input = match expr.kind {
2524 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
2525 hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2526 hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
2527 _ => None,
2528 },
2529 _ => None,
2530 };
2531
2532 lit_input
2533 .filter(|l| !l.ty.has_aliases())
2536 .map(|l| tcx.at(expr.span).lit_to_const(l))
2537 }
2538
2539 fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2540 let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2541 match idx {
2542 hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2543 hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2544 }
2545 }
2546
2547 #[instrument(level = "debug", skip(self), ret)]
2549 pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2550 let tcx = self.tcx();
2551
2552 let result_ty = match &hir_ty.kind {
2553 hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2554 hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2555 hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2556 hir::TyKind::Ref(region, mt) => {
2557 let r = self.lower_lifetime(region, RegionInferReason::Reference);
2558 debug!(?r);
2559 let t = self.lower_ty(mt.ty);
2560 Ty::new_ref(tcx, r, t, mt.mutbl)
2561 }
2562 hir::TyKind::Never => tcx.types.never,
2563 hir::TyKind::Tup(fields) => {
2564 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2565 }
2566 hir::TyKind::BareFn(bf) => {
2567 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span);
2568
2569 Ty::new_fn_ptr(
2570 tcx,
2571 self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2572 )
2573 }
2574 hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2575 tcx,
2576 ty::Binder::bind_with_vars(
2577 self.lower_ty(binder.inner_ty),
2578 tcx.late_bound_vars(hir_ty.hir_id),
2579 ),
2580 ),
2581 hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2582 let lifetime = tagged_ptr.pointer();
2583 let repr = tagged_ptr.tag();
2584
2585 if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2586 Ty::new_error(tcx, guar)
2590 } else {
2591 let repr = match repr {
2592 TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2593 TraitObjectSyntax::DynStar => ty::DynStar,
2594 };
2595 self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2596 }
2597 }
2598 hir::TyKind::Path(hir::QPath::Resolved(_, path))
2602 if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2603 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2604 }) =>
2605 {
2606 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2607 Ty::new_error(tcx, guar)
2608 }
2609 hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2610 debug!(?maybe_qself, ?path);
2611 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2612 self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
2613 }
2614 &hir::TyKind::OpaqueDef(opaque_ty) => {
2615 let in_trait = match opaque_ty.origin {
2619 hir::OpaqueTyOrigin::FnReturn {
2620 in_trait_or_impl: Some(hir::RpitContext::Trait),
2621 ..
2622 }
2623 | hir::OpaqueTyOrigin::AsyncFn {
2624 in_trait_or_impl: Some(hir::RpitContext::Trait),
2625 ..
2626 } => true,
2627 hir::OpaqueTyOrigin::FnReturn {
2628 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2629 ..
2630 }
2631 | hir::OpaqueTyOrigin::AsyncFn {
2632 in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2633 ..
2634 }
2635 | hir::OpaqueTyOrigin::TyAlias { .. } => false,
2636 };
2637
2638 self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2639 }
2640 hir::TyKind::TraitAscription(hir_bounds) => {
2641 let self_ty = self.ty_infer(None, hir_ty.span);
2644 let mut bounds = Vec::new();
2645 self.lower_bounds(
2646 self_ty,
2647 hir_bounds.iter(),
2648 &mut bounds,
2649 ty::List::empty(),
2650 PredicateFilter::All,
2651 );
2652 self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2653 self_ty
2654 }
2655 hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2659 if segment.args.is_some_and(|args| {
2660 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2661 }) =>
2662 {
2663 let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2664 Ty::new_error(tcx, guar)
2665 }
2666 hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
2667 debug!(?qself, ?segment);
2668 let ty = self.lower_ty(qself);
2669 self.lower_assoc_path_ty(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
2670 .map(|(ty, _, _)| ty)
2671 .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2672 }
2673 &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
2674 let def_id = tcx.require_lang_item(lang_item, Some(span));
2675 let (args, _) = self.lower_generic_args_of_path(
2676 span,
2677 def_id,
2678 &[],
2679 &hir::PathSegment::invalid(),
2680 None,
2681 );
2682 tcx.at(span).type_of(def_id).instantiate(tcx, args)
2683 }
2684 hir::TyKind::Array(ty, length) => {
2685 let length = self.lower_const_arg(length, FeedConstTy::No);
2686 Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2687 }
2688 hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
2689 hir::TyKind::Infer(()) => {
2690 self.ty_infer(None, hir_ty.span)
2695 }
2696 hir::TyKind::Pat(ty, pat) => {
2697 let ty_span = ty.span;
2698 let ty = self.lower_ty(ty);
2699 let pat_ty = match pat.kind {
2700 hir::TyPatKind::Range(start, end) => {
2701 let (ty, start, end) = match ty.kind() {
2702 ty::Int(_) | ty::Uint(_) | ty::Char => {
2705 let start = self.lower_const_arg(start, FeedConstTy::No);
2706 let end = self.lower_const_arg(end, FeedConstTy::No);
2707 (ty, start, end)
2708 }
2709 _ => {
2710 let guar = self.dcx().span_delayed_bug(
2711 ty_span,
2712 "invalid base type for range pattern",
2713 );
2714 let errc = ty::Const::new_error(tcx, guar);
2715 (Ty::new_error(tcx, guar), errc, errc)
2716 }
2717 };
2718
2719 let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
2720 Ty::new_pat(tcx, ty, pat)
2721 }
2722 hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
2723 };
2724 self.record_ty(pat.hir_id, ty, pat.span);
2725 pat_ty
2726 }
2727 hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2728 };
2729
2730 self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
2731 result_ty
2732 }
2733
2734 #[instrument(level = "debug", skip(self), ret)]
2736 fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
2737 let tcx = self.tcx();
2738
2739 let lifetimes = tcx.opaque_captured_lifetimes(def_id);
2740 debug!(?lifetimes);
2741
2742 let def_id = if in_trait {
2746 tcx.associated_type_for_impl_trait_in_trait(def_id).to_def_id()
2747 } else {
2748 def_id.to_def_id()
2749 };
2750
2751 let generics = tcx.generics_of(def_id);
2752 debug!(?generics);
2753
2754 let offset = generics.count() - lifetimes.len();
2758
2759 let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
2760 if let Some(i) = (param.index as usize).checked_sub(offset) {
2761 let (lifetime, _) = lifetimes[i];
2762 self.lower_resolved_lifetime(lifetime).into()
2763 } else {
2764 tcx.mk_param_from_def(param)
2765 }
2766 });
2767 debug!(?args);
2768
2769 if in_trait {
2770 Ty::new_projection_from_args(tcx, def_id, args)
2771 } else {
2772 Ty::new_opaque(tcx, def_id, args)
2773 }
2774 }
2775
2776 pub fn lower_arg_ty(&self, ty: &hir::Ty<'tcx>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
2777 match ty.kind {
2778 hir::TyKind::Infer(()) if let Some(expected_ty) = expected_ty => {
2779 self.record_ty(ty.hir_id, expected_ty, ty.span);
2780 expected_ty
2781 }
2782 _ => self.lower_ty(ty),
2783 }
2784 }
2785
2786 #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
2788 pub fn lower_fn_ty(
2789 &self,
2790 hir_id: HirId,
2791 safety: hir::Safety,
2792 abi: rustc_abi::ExternAbi,
2793 decl: &hir::FnDecl<'tcx>,
2794 generics: Option<&hir::Generics<'_>>,
2795 hir_ty: Option<&hir::Ty<'_>>,
2796 ) -> ty::PolyFnSig<'tcx> {
2797 let tcx = self.tcx();
2798 let bound_vars = tcx.late_bound_vars(hir_id);
2799 debug!(?bound_vars);
2800
2801 let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
2802
2803 debug!(?output_ty);
2804
2805 let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
2806 let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2807
2808 if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2809 tcx.hir_node(hir_id)
2810 {
2811 check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2812 }
2813
2814 cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
2816
2817 if !bare_fn_ty.references_error() {
2818 let inputs = bare_fn_ty.inputs();
2825 let late_bound_in_args =
2826 tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
2827 let output = bare_fn_ty.output();
2828 let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
2829
2830 self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2831 struct_span_code_err!(
2832 self.dcx(),
2833 decl.output.span(),
2834 E0581,
2835 "return type references {}, which is not constrained by the fn input types",
2836 br_name
2837 )
2838 });
2839 }
2840
2841 bare_fn_ty
2842 }
2843
2844 pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
2849 &self,
2850 fn_hir_id: HirId,
2851 arg_idx: Option<usize>,
2852 ) -> Option<Ty<'tcx>> {
2853 let tcx = self.tcx();
2854 let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2855 tcx.hir_node(fn_hir_id)
2856 else {
2857 return None;
2858 };
2859 let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
2860
2861 let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty));
2862
2863 let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
2864 tcx,
2865 *ident,
2866 ty::AssocKind::Fn,
2867 trait_ref.def_id,
2868 )?;
2869
2870 let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
2871 tcx,
2872 trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2873 );
2874 let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2875
2876 Some(if let Some(arg_idx) = arg_idx {
2877 *fn_sig.inputs().get(arg_idx)?
2878 } else {
2879 fn_sig.output()
2880 })
2881 }
2882
2883 #[instrument(level = "trace", skip(self, generate_err))]
2884 fn validate_late_bound_regions<'cx>(
2885 &'cx self,
2886 constrained_regions: FxIndexSet<ty::BoundRegionKind>,
2887 referenced_regions: FxIndexSet<ty::BoundRegionKind>,
2888 generate_err: impl Fn(&str) -> Diag<'cx>,
2889 ) {
2890 for br in referenced_regions.difference(&constrained_regions) {
2891 let br_name = match *br {
2892 ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2893 | ty::BoundRegionKind::Anon
2894 | ty::BoundRegionKind::ClosureEnv => "an anonymous lifetime".to_string(),
2895 ty::BoundRegionKind::Named(_, name) => format!("lifetime `{name}`"),
2896 };
2897
2898 let mut err = generate_err(&br_name);
2899
2900 if let ty::BoundRegionKind::Named(_, kw::UnderscoreLifetime)
2901 | ty::BoundRegionKind::Anon = *br
2902 {
2903 err.note(
2910 "lifetimes appearing in an associated or opaque type are not considered constrained",
2911 );
2912 err.note("consider introducing a named lifetime parameter");
2913 }
2914
2915 err.emit();
2916 }
2917 }
2918
2919 #[instrument(level = "debug", skip(self, span), ret)]
2927 fn compute_object_lifetime_bound(
2928 &self,
2929 span: Span,
2930 existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2931 ) -> Option<ty::Region<'tcx>> {
2933 let tcx = self.tcx();
2934
2935 let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2938
2939 if derived_region_bounds.is_empty() {
2942 return None;
2943 }
2944
2945 if derived_region_bounds.iter().any(|r| r.is_static()) {
2948 return Some(tcx.lifetimes.re_static);
2949 }
2950
2951 let r = derived_region_bounds[0];
2955 if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2956 self.dcx().emit_err(AmbiguousLifetimeBound { span });
2957 }
2958 Some(r)
2959 }
2960}