@@ -202,18 +202,20 @@ pub trait HirTyLowerer<'tcx> {
202
202
/// The "qualified self" of an associated item path.
203
203
///
204
204
/// For diagnostic purposes only.
205
- enum AssocItemQSelf {
205
+ enum AssocItemQSelf < ' tcx > {
206
206
Trait ( DefId ) ,
207
207
TyParam ( LocalDefId , Span ) ,
208
208
SelfTyAlias ,
209
+ AssocTy ( Ty < ' tcx > ) ,
209
210
}
210
211
211
- impl AssocItemQSelf {
212
- fn to_string ( & self , tcx : TyCtxt < ' _ > ) -> String {
212
+ impl < ' tcx > AssocItemQSelf < ' tcx > {
213
+ fn to_string ( & self , tcx : TyCtxt < ' tcx > ) -> String {
213
214
match * self {
214
215
Self :: Trait ( def_id) => tcx. def_path_str ( def_id) ,
215
216
Self :: TyParam ( def_id, _) => tcx. hir ( ) . ty_param_name ( def_id) . to_string ( ) ,
216
217
Self :: SelfTyAlias => kw:: SelfUpper . to_string ( ) ,
218
+ Self :: AssocTy ( ty) => ty. to_string ( ) ,
217
219
}
218
220
}
219
221
}
@@ -925,7 +927,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
925
927
fn probe_single_bound_for_assoc_item < I > (
926
928
& self ,
927
929
all_candidates : impl Fn ( ) -> I ,
928
- qself : AssocItemQSelf ,
930
+ qself : AssocItemQSelf < ' tcx > ,
929
931
assoc_kind : ty:: AssocKind ,
930
932
assoc_name : Ident ,
931
933
span : Span ,
@@ -1147,15 +1149,45 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1147
1149
) ?
1148
1150
}
1149
1151
(
1150
- & ty:: Param ( _) ,
1151
- Res :: SelfTyParam { trait_ : param_did } | Res :: Def ( DefKind :: TyParam , param_did) ,
1152
+ ty:: Param ( _) ,
1153
+ Res :: SelfTyParam { trait_ : param_def_id }
1154
+ | Res :: Def ( DefKind :: TyParam , param_def_id) ,
1152
1155
) => self . probe_single_ty_param_bound_for_assoc_item (
1153
- param_did . expect_local ( ) ,
1156
+ param_def_id . expect_local ( ) ,
1154
1157
qself. span ,
1155
1158
ty:: AssocKind :: Type ,
1156
1159
assoc_ident,
1157
1160
span,
1158
1161
) ?,
1162
+ // FIXME(fmease):
1163
+ // Require the pre-lowered projectee (the HIR QSelf) to have `DefKind::AssocTy`. Rephrased,
1164
+ // `T::Assoc::Assoc` typeck'ing shouldn't imply `Identity<T::Assoc>::Assoc` typeck'ing where
1165
+ // `Identity` is an eager (i.e., non-lazy) type alias. We should do this
1166
+ // * for consistency with lazy type aliases (`ty::Weak`)
1167
+ // * for consistency with the fact that `T::Assoc` typeck'ing doesn't imply `Identity<T>::Assoc`
1168
+ // typeck'ing
1169
+ ( ty:: Alias ( ty:: Projection , alias_ty) , _ /* Res::Def(DefKind::AssocTy, _) */ ) => {
1170
+ // FIXME: Utilizing `item_bounds` for this is cycle-prone.
1171
+ let predicates = tcx. item_bounds ( alias_ty. def_id ) . instantiate ( tcx, alias_ty. args ) ;
1172
+
1173
+ self . probe_single_bound_for_assoc_item (
1174
+ || {
1175
+ let trait_refs = predicates. iter ( ) . filter_map ( |pred| {
1176
+ pred. as_trait_clause ( ) . map ( |t| t. map_bound ( |t| t. trait_ref ) )
1177
+ } ) ;
1178
+ traits:: transitive_bounds_that_define_assoc_item (
1179
+ tcx,
1180
+ trait_refs,
1181
+ assoc_ident,
1182
+ )
1183
+ } ,
1184
+ AssocItemQSelf :: AssocTy ( qself_ty) ,
1185
+ ty:: AssocKind :: Type ,
1186
+ assoc_ident,
1187
+ span,
1188
+ None ,
1189
+ ) ?
1190
+ }
1159
1191
_ => {
1160
1192
let reported = if variant_resolution. is_some ( ) {
1161
1193
// Variant in type position
@@ -1303,6 +1335,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1303
1335
) ;
1304
1336
} ) ;
1305
1337
}
1338
+
1306
1339
Ok ( ( ty, DefKind :: AssocTy , assoc_ty. def_id ) )
1307
1340
}
1308
1341
0 commit comments