@@ -39,6 +39,7 @@ use rustc_infer::traits::ObligationCause;
3939use rustc_middle:: middle:: stability:: AllowUnstable ;
4040use rustc_middle:: mir:: interpret:: { LitToConstError , LitToConstInput } ;
4141use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
42+ use rustc_middle:: ty:: typeck_results:: { HasTypeDependentDefs , TypeDependentDef } ;
4243use rustc_middle:: ty:: {
4344 self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty , TyCtxt ,
4445 TypeVisitableExt ,
@@ -98,7 +99,7 @@ pub enum RegionInferReason<'a> {
9899/// the [`rustc_middle::ty`] representation.
99100///
100101/// This trait used to be called `AstConv`.
101- pub trait HirTyLowerer < ' tcx > {
102+ pub trait HirTyLowerer < ' tcx > : HasTypeDependentDefs {
102103 fn tcx ( & self ) -> TyCtxt < ' tcx > ;
103104
104105 /// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
@@ -173,6 +174,8 @@ pub trait HirTyLowerer<'tcx> {
173174 /// Record the lowered type of a HIR node in this context.
174175 fn record_ty ( & self , hir_id : HirId , ty : Ty < ' tcx > , span : Span ) ;
175176
177+ fn record_res ( & self , hir_id : hir:: HirId , result : TypeDependentDef ) ;
178+
176179 /// The inference context of the lowering context if applicable.
177180 fn infcx ( & self ) -> Option < & InferCtxt < ' tcx > > ;
178181
@@ -192,6 +195,8 @@ pub trait HirTyLowerer<'tcx> {
192195 {
193196 self
194197 }
198+
199+ fn upcast ( & self ) -> & dyn HasTypeDependentDefs ;
195200}
196201
197202/// New-typed boolean indicating whether explicit late-bound lifetimes
@@ -992,6 +997,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
992997 /// [type-relative]: hir::QPath::TypeRelative
993998 /// [#22519]: https://github.com/rust-lang/rust/issues/22519
994999 /// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
1000+ // FIXME(fmease): Update docs
9951001 //
9961002 // NOTE: When this function starts resolving `Trait::AssocTy` successfully
9971003 // it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
@@ -1006,13 +1012,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10061012 permit_variants : bool ,
10071013 ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
10081014 debug ! ( %qself_ty, ?assoc_segment. ident) ;
1015+ let result = self . lower_assoc_path_inner (
1016+ hir_ref_id,
1017+ span,
1018+ qself_ty,
1019+ qself,
1020+ assoc_segment,
1021+ permit_variants,
1022+ ) ;
1023+ self . record_res ( hir_ref_id, result. map ( |( _, def_kind, def_id) | ( def_kind, def_id) ) ) ;
1024+ result
1025+ }
1026+
1027+ fn lower_assoc_path_inner (
1028+ & self ,
1029+ hir_ref_id : HirId ,
1030+ span : Span ,
1031+ qself_ty : Ty < ' tcx > ,
1032+ qself : & ' tcx hir:: Ty < ' tcx > ,
1033+ assoc_segment : & ' tcx hir:: PathSegment < ' tcx > ,
1034+ permit_variants : bool ,
1035+ ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorGuaranteed > {
10091036 let tcx = self . tcx ( ) ;
10101037
10111038 let assoc_ident = assoc_segment. ident ;
1012- let qself_res = if let hir:: TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) = & qself. kind {
1013- path. res
1014- } else {
1015- Res :: Err
1039+ let qself_res = match & qself. kind {
1040+ hir:: TyKind :: Path ( qpath) => self . upcast ( ) . qpath_res ( qpath, qself. hir_id ) ,
1041+ _ => Res :: Err ,
10161042 } ;
10171043
10181044 // Check if we have an enum variant or an inherent associated type.
@@ -1038,15 +1064,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10381064 }
10391065
10401066 // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1041- if let Some ( ( ty, did ) ) = self . probe_inherent_assoc_ty (
1067+ if let Some ( ( ty, def_id ) ) = self . probe_inherent_assoc_ty (
10421068 assoc_ident,
10431069 assoc_segment,
10441070 adt_def. did ( ) ,
10451071 qself_ty,
10461072 hir_ref_id,
10471073 span,
10481074 ) ? {
1049- return Ok ( ( ty, DefKind :: AssocTy , did ) ) ;
1075+ return Ok ( ( ty, DefKind :: AssocTy , def_id ) ) ;
10501076 }
10511077 }
10521078
@@ -1077,13 +1103,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10771103 ) ?
10781104 }
10791105 (
1080- & ty:: Param ( _) ,
1081- Res :: SelfTyParam { trait_ : param_did } | Res :: Def ( DefKind :: TyParam , param_did) ,
1106+ ty:: Param ( _) ,
1107+ Res :: SelfTyParam { trait_ : param_def_id }
1108+ | Res :: Def ( DefKind :: TyParam , param_def_id) ,
10821109 ) => self . probe_single_ty_param_bound_for_assoc_ty (
1083- param_did . expect_local ( ) ,
1110+ param_def_id . expect_local ( ) ,
10841111 assoc_ident,
10851112 span,
10861113 ) ?,
1114+ ( ty:: Alias ( ty:: Projection , alias_ty) , Res :: Def ( DefKind :: AssocTy , _) ) => {
1115+ // FIXME: Utilizing `item_bounds` for this is cycle-prone.
1116+ let predicates = tcx. item_bounds ( alias_ty. def_id ) . instantiate ( tcx, alias_ty. args ) ;
1117+
1118+ self . probe_single_bound_for_assoc_item (
1119+ || {
1120+ let trait_refs = predicates. iter ( ) . filter_map ( |pred| {
1121+ pred. as_trait_clause ( ) . map ( |t| t. map_bound ( |t| t. trait_ref ) )
1122+ } ) ;
1123+ traits:: transitive_bounds_that_define_assoc_item (
1124+ tcx,
1125+ trait_refs,
1126+ assoc_ident,
1127+ )
1128+ } ,
1129+ qself_ty,
1130+ None ,
1131+ ty:: AssocKind :: Type ,
1132+ assoc_ident,
1133+ span,
1134+ None ,
1135+ ) ?
1136+ }
10871137 _ => {
10881138 let reported = if variant_resolution. is_some ( ) {
10891139 // Variant in type position
@@ -1187,6 +1237,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11871237 ) ;
11881238 } ) ;
11891239 }
1240+
11901241 Ok ( ( ty, DefKind :: AssocTy , assoc_ty. def_id ) )
11911242 }
11921243
0 commit comments