@@ -236,18 +236,20 @@ pub trait HirTyLowerer<'tcx> {
236236/// The "qualified self" of an associated item path.
237237///
238238/// For diagnostic purposes only.
239- enum AssocItemQSelf {
239+ enum AssocItemQSelf < ' tcx > {
240240 Trait ( DefId ) ,
241241 TyParam ( LocalDefId , Span ) ,
242242 SelfTyAlias ,
243+ AssocTy ( Ty < ' tcx > ) ,
243244}
244245
245- impl AssocItemQSelf {
246- fn to_string ( & self , tcx : TyCtxt < ' _ > ) -> String {
246+ impl < ' tcx > AssocItemQSelf < ' tcx > {
247+ fn to_string ( & self , tcx : TyCtxt < ' tcx > ) -> String {
247248 match * self {
248249 Self :: Trait ( def_id) => tcx. def_path_str ( def_id) ,
249250 Self :: TyParam ( def_id, _) => tcx. hir_ty_param_name ( def_id) . to_string ( ) ,
250251 Self :: SelfTyAlias => kw:: SelfUpper . to_string ( ) ,
252+ Self :: AssocTy ( ty) => ty. to_string ( ) ,
251253 }
252254 }
253255}
@@ -1091,7 +1093,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
10911093 fn probe_single_bound_for_assoc_item < I > (
10921094 & self ,
10931095 all_candidates : impl Fn ( ) -> I ,
1094- qself : AssocItemQSelf ,
1096+ qself : AssocItemQSelf < ' tcx > ,
10951097 assoc_tag : ty:: AssocTag ,
10961098 assoc_ident : Ident ,
10971099 span : Span ,
@@ -1442,15 +1444,45 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14421444 ) ?
14431445 }
14441446 (
1445- & ty:: Param ( _) ,
1446- Res :: SelfTyParam { trait_ : param_did } | Res :: Def ( DefKind :: TyParam , param_did) ,
1447+ ty:: Param ( _) ,
1448+ Res :: SelfTyParam { trait_ : param_def_id }
1449+ | Res :: Def ( DefKind :: TyParam , param_def_id) ,
14471450 ) => self . probe_single_ty_param_bound_for_assoc_item (
1448- param_did . expect_local ( ) ,
1451+ param_def_id . expect_local ( ) ,
14491452 hir_self_ty. span ,
14501453 assoc_tag,
14511454 segment. ident ,
14521455 span,
14531456 ) ?,
1457+ // FIXME(fmease):
1458+ // Require the pre-lowered projectee (the HIR QSelf) to have `DefKind::AssocTy`. Rephrased,
1459+ // `T::Assoc::Assoc` typeck'ing shouldn't imply `Identity<T::Assoc>::Assoc` typeck'ing where
1460+ // `Identity` is an eager (i.e., non-lazy) type alias. We should do this
1461+ // * for consistency with lazy type aliases (`ty::Weak`)
1462+ // * for consistency with the fact that `T::Assoc` typeck'ing doesn't imply `Identity<T>::Assoc`
1463+ // typeck'ing
1464+ ( ty:: Alias ( ty:: Projection , alias_ty) , _ /* Res::Def(DefKind::AssocTy, _) */ ) => {
1465+ // FIXME: Utilizing `item_bounds` for this is cycle-prone.
1466+ let predicates = tcx. item_bounds ( alias_ty. def_id ) . instantiate ( tcx, alias_ty. args ) ;
1467+
1468+ self . probe_single_bound_for_assoc_item (
1469+ || {
1470+ let trait_refs = predicates. iter ( ) . filter_map ( |pred| {
1471+ pred. as_trait_clause ( ) . map ( |t| t. map_bound ( |t| t. trait_ref ) )
1472+ } ) ;
1473+ traits:: transitive_bounds_that_define_assoc_item (
1474+ tcx,
1475+ trait_refs,
1476+ segment. ident ,
1477+ )
1478+ } ,
1479+ AssocItemQSelf :: AssocTy ( self_ty) ,
1480+ assoc_tag,
1481+ segment. ident ,
1482+ span,
1483+ None ,
1484+ ) ?
1485+ }
14541486 _ => {
14551487 return Err ( self . report_unresolved_type_relative_path (
14561488 self_ty,
0 commit comments