@@ -208,18 +208,20 @@ pub trait HirTyLowerer<'tcx> {
208208/// The "qualified self" of an associated item path.
209209///
210210/// For diagnostic purposes only.
211- enum AssocItemQSelf {
211+ enum AssocItemQSelf < ' tcx > {
212212 Trait ( DefId ) ,
213213 TyParam ( LocalDefId , Span ) ,
214214 SelfTyAlias ,
215+ AssocTy ( Ty < ' tcx > ) ,
215216}
216217
217- impl AssocItemQSelf {
218- fn to_string ( & self , tcx : TyCtxt < ' _ > ) -> String {
218+ impl < ' tcx > AssocItemQSelf < ' tcx > {
219+ fn to_string ( & self , tcx : TyCtxt < ' tcx > ) -> String {
219220 match * self {
220221 Self :: Trait ( def_id) => tcx. def_path_str ( def_id) ,
221222 Self :: TyParam ( def_id, _) => tcx. hir_ty_param_name ( def_id) . to_string ( ) ,
222223 Self :: SelfTyAlias => kw:: SelfUpper . to_string ( ) ,
224+ Self :: AssocTy ( ty) => ty. to_string ( ) ,
223225 }
224226 }
225227}
@@ -1010,8 +1012,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10101012 fn probe_single_bound_for_assoc_item < I > (
10111013 & self ,
10121014 all_candidates : impl Fn ( ) -> I ,
1013- qself : AssocItemQSelf ,
1014- assoc_tag : AssocTag ,
1015+ qself : AssocItemQSelf < ' tcx > ,
1016+ assoc_tag : ty :: AssocTag ,
10151017 assoc_ident : Ident ,
10161018 span : Span ,
10171019 constraint : Option < & hir:: AssocItemConstraint < ' tcx > > ,
@@ -1305,15 +1307,45 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13051307 ) ?
13061308 }
13071309 (
1308- & ty:: Param ( _) ,
1309- Res :: SelfTyParam { trait_ : param_did } | Res :: Def ( DefKind :: TyParam , param_did) ,
1310+ ty:: Param ( _) ,
1311+ Res :: SelfTyParam { trait_ : param_def_id }
1312+ | Res :: Def ( DefKind :: TyParam , param_def_id) ,
13101313 ) => self . probe_single_ty_param_bound_for_assoc_item (
1311- param_did . expect_local ( ) ,
1314+ param_def_id . expect_local ( ) ,
13121315 qself. span ,
13131316 mode. assoc_tag ( ) ,
13141317 assoc_ident,
13151318 span,
13161319 ) ?,
1320+ // FIXME(fmease):
1321+ // Require the pre-lowered projectee (the HIR QSelf) to have `DefKind::AssocTy`. Rephrased,
1322+ // `T::Assoc::Assoc` typeck'ing shouldn't imply `Identity<T::Assoc>::Assoc` typeck'ing where
1323+ // `Identity` is an eager (i.e., non-lazy) type alias. We should do this
1324+ // * for consistency with lazy type aliases (`ty::Weak`)
1325+ // * for consistency with the fact that `T::Assoc` typeck'ing doesn't imply `Identity<T>::Assoc`
1326+ // typeck'ing
1327+ ( ty:: Alias ( ty:: Projection , alias_ty) , _ /* Res::Def(DefKind::AssocTy, _) */ ) => {
1328+ // FIXME: Utilizing `item_bounds` for this is cycle-prone.
1329+ let predicates = tcx. item_bounds ( alias_ty. def_id ) . instantiate ( tcx, alias_ty. args ) ;
1330+
1331+ self . probe_single_bound_for_assoc_item (
1332+ || {
1333+ let trait_refs = predicates. iter ( ) . filter_map ( |pred| {
1334+ pred. as_trait_clause ( ) . map ( |t| t. map_bound ( |t| t. trait_ref ) )
1335+ } ) ;
1336+ traits:: transitive_bounds_that_define_assoc_item (
1337+ tcx,
1338+ trait_refs,
1339+ assoc_ident,
1340+ )
1341+ } ,
1342+ AssocItemQSelf :: AssocTy ( qself_ty) ,
1343+ ty:: AssocKind :: Type ,
1344+ assoc_ident,
1345+ span,
1346+ None ,
1347+ ) ?
1348+ }
13171349 _ => {
13181350 let kind_str = assoc_tag_str ( mode. assoc_tag ( ) ) ;
13191351 let reported = if variant_resolution. is_some ( ) {
@@ -1466,6 +1498,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14661498 ) ;
14671499 } ) ;
14681500 }
1501+
14691502 Ok ( result)
14701503 }
14711504
0 commit comments