@@ -208,18 +208,20 @@ pub trait HirTyLowerer<'tcx> {
208
208
/// The "qualified self" of an associated item path.
209
209
///
210
210
/// For diagnostic purposes only.
211
- enum AssocItemQSelf {
211
+ enum AssocItemQSelf < ' tcx > {
212
212
Trait ( DefId ) ,
213
213
TyParam ( LocalDefId , Span ) ,
214
214
SelfTyAlias ,
215
+ AssocTy ( Ty < ' tcx > ) ,
215
216
}
216
217
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 {
219
220
match * self {
220
221
Self :: Trait ( def_id) => tcx. def_path_str ( def_id) ,
221
222
Self :: TyParam ( def_id, _) => tcx. hir_ty_param_name ( def_id) . to_string ( ) ,
222
223
Self :: SelfTyAlias => kw:: SelfUpper . to_string ( ) ,
224
+ Self :: AssocTy ( ty) => ty. to_string ( ) ,
223
225
}
224
226
}
225
227
}
@@ -1010,8 +1012,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1010
1012
fn probe_single_bound_for_assoc_item < I > (
1011
1013
& self ,
1012
1014
all_candidates : impl Fn ( ) -> I ,
1013
- qself : AssocItemQSelf ,
1014
- assoc_tag : AssocTag ,
1015
+ qself : AssocItemQSelf < ' tcx > ,
1016
+ assoc_tag : ty :: AssocTag ,
1015
1017
assoc_ident : Ident ,
1016
1018
span : Span ,
1017
1019
constraint : Option < & hir:: AssocItemConstraint < ' tcx > > ,
@@ -1305,15 +1307,45 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1305
1307
) ?
1306
1308
}
1307
1309
(
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) ,
1310
1313
) => self . probe_single_ty_param_bound_for_assoc_item (
1311
- param_did . expect_local ( ) ,
1314
+ param_def_id . expect_local ( ) ,
1312
1315
qself. span ,
1313
1316
mode. assoc_tag ( ) ,
1314
1317
assoc_ident,
1315
1318
span,
1316
1319
) ?,
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
+ mode. assoc_tag ( ) ,
1344
+ assoc_ident,
1345
+ span,
1346
+ None ,
1347
+ ) ?
1348
+ }
1317
1349
_ => {
1318
1350
let kind_str = assoc_tag_str ( mode. assoc_tag ( ) ) ;
1319
1351
let reported = if variant_resolution. is_some ( ) {
@@ -1466,6 +1498,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1466
1498
) ;
1467
1499
} ) ;
1468
1500
}
1501
+
1469
1502
Ok ( result)
1470
1503
}
1471
1504
0 commit comments