@@ -47,7 +47,7 @@ use crate::{
47
47
to_assoc_type_id, to_chalk_trait_id,
48
48
traits:: ChalkContext ,
49
49
utils:: ClosureSubst ,
50
- wrap_empty_binders,
50
+ variable_kinds_from_generics , wrap_empty_binders,
51
51
} ;
52
52
53
53
pub ( crate ) type AssociatedTyDatum = chalk_solve:: rust_ir:: AssociatedTyDatum < Interner > ;
@@ -1031,9 +1031,14 @@ fn impl_method_rpitit_values(
1031
1031
DebruijnIndex :: INNERMOST ,
1032
1032
) ;
1033
1033
let trait_assoc = trait_assoc_id. loc ( db) ;
1034
+ // Completely unlike the docs, Chalk requires both the impl generics and the associated type
1035
+ // generics in the binder.
1034
1036
let impl_rpitit_binders = VariableKinds :: from_iter (
1035
1037
Interner ,
1036
- & trait_assoc. bounds . binders . as_slice ( Interner ) [ ..trait_method_generics. len ( ) ] ,
1038
+ trait_assoc. bounds . binders . as_slice ( Interner ) [ ..trait_method_generics. len ( ) ]
1039
+ . iter ( )
1040
+ . cloned ( )
1041
+ . chain ( variable_kinds_from_generics ( db, impl_method_generics. iter_parent_id ( ) ) ) ,
1037
1042
) ;
1038
1043
let impl_rpitit = Binders :: new (
1039
1044
impl_rpitit_binders,
@@ -1258,44 +1263,49 @@ pub(crate) fn associated_ty_value_query(
1258
1263
AnyImplAssocType :: Normal ( type_alias) => {
1259
1264
type_alias_associated_ty_value ( db, krate, type_alias)
1260
1265
}
1261
- AnyImplAssocType :: Rpitit ( assoc_type_id) => {
1262
- let assoc_type = assoc_type_id. loc ( db) ;
1263
- let trait_assoc = assoc_type. trait_assoc . loc ( db) ;
1264
- let all_method_assocs = impl_method_rpitit_values (
1265
- db,
1266
- assoc_type. impl_id ,
1267
- trait_assoc. synthesized_from_method ,
1268
- ) ;
1269
- let trait_assoc_id = to_assoc_type_id_rpitit ( assoc_type. trait_assoc ) ;
1270
- all_method_assocs
1271
- . iter ( )
1272
- . find ( |method_assoc| method_assoc. associated_ty_id == trait_assoc_id)
1273
- . cloned ( )
1274
- . unwrap_or_else ( || {
1275
- let impl_id = hir_def:: ImplId :: to_chalk ( assoc_type. impl_id , db) ;
1276
- let trait_method_generics =
1277
- generics ( db. upcast ( ) , trait_assoc. synthesized_from_method . into ( ) ) ;
1278
- Arc :: new ( AssociatedTyValue {
1279
- associated_ty_id : trait_assoc_id,
1280
- impl_id,
1281
- // In this situation, we don't know even that the trait and impl generics match, therefore
1282
- // the only binders we can give to comply with the trait's binders are the trait's binders.
1283
- // However, for impl associated types chalk wants only their own generics, excluding
1284
- // those of the impl (unlike in traits), therefore we filter them here.
1285
- value : Binders :: new (
1286
- VariableKinds :: from_iter (
1287
- Interner ,
1288
- & trait_assoc. bounds . binders . as_slice ( Interner )
1289
- [ ..trait_method_generics. len_self ( ) ] ,
1290
- ) ,
1291
- rust_ir:: AssociatedTyValueBound { ty : TyKind :: Error . intern ( Interner ) } ,
1292
- ) ,
1293
- } )
1294
- } )
1295
- }
1266
+ AnyImplAssocType :: Rpitit ( assoc_type_id) => rpitit_associated_ty_value ( db, assoc_type_id) ,
1296
1267
}
1297
1268
}
1298
1269
1270
+ fn rpitit_associated_ty_value (
1271
+ db : & dyn HirDatabase ,
1272
+ assoc_type_id : RpititImplAssocTyId ,
1273
+ ) -> Arc < AssociatedTyValue > {
1274
+ let assoc_type = assoc_type_id. loc ( db) ;
1275
+ let trait_assoc = assoc_type. trait_assoc . loc ( db) ;
1276
+ let all_method_assocs =
1277
+ impl_method_rpitit_values ( db, assoc_type. impl_id , trait_assoc. synthesized_from_method ) ;
1278
+ let trait_assoc_id = to_assoc_type_id_rpitit ( assoc_type. trait_assoc ) ;
1279
+ all_method_assocs
1280
+ . iter ( )
1281
+ . find ( |method_assoc| method_assoc. associated_ty_id == trait_assoc_id)
1282
+ . cloned ( )
1283
+ . unwrap_or_else ( || {
1284
+ let impl_id = hir_def:: ImplId :: to_chalk ( assoc_type. impl_id , db) ;
1285
+ let trait_method_generics =
1286
+ generics ( db. upcast ( ) , trait_assoc. synthesized_from_method . into ( ) ) ;
1287
+ let impl_generics = generics ( db. upcast ( ) , assoc_type. impl_id . into ( ) ) ;
1288
+ // In this situation, we don't know even that the trait and impl generics match, therefore
1289
+ // the only binders we can give to comply with the trait's binders are the trait's binders.
1290
+ // However, for impl associated types chalk wants only their own generics, excluding
1291
+ // those of the impl (unlike in traits), therefore we filter them here.
1292
+ // Completely unlike the docs, Chalk requires both the impl generics and the associated type
1293
+ // generics in the binder.
1294
+ let value = Binders :: new (
1295
+ VariableKinds :: from_iter (
1296
+ Interner ,
1297
+ trait_assoc. bounds . binders . as_slice ( Interner )
1298
+ [ ..trait_method_generics. len_self ( ) ]
1299
+ . iter ( )
1300
+ . cloned ( )
1301
+ . chain ( variable_kinds_from_generics ( db, impl_generics. iter_id ( ) ) ) ,
1302
+ ) ,
1303
+ rust_ir:: AssociatedTyValueBound { ty : TyKind :: Error . intern ( Interner ) } ,
1304
+ ) ;
1305
+ Arc :: new ( AssociatedTyValue { associated_ty_id : trait_assoc_id, impl_id, value } )
1306
+ } )
1307
+ }
1308
+
1299
1309
fn type_alias_associated_ty_value (
1300
1310
db : & dyn HirDatabase ,
1301
1311
_krate : Crate ,
0 commit comments